正则表达式(stringr包)

前言

R语言的stringr包是由大名鼎鼎的Hadley Wickham开发,是对于stringi的进一步封装。这个人有多牛,因为他数据处理和可视化开发工具方面的突出贡献,获得专为统计计算而设立的约翰·钱伯斯奖,这在当年可是让一众统计学家大呼不满。Hadley Wickham通过开发ggplot2包让人们意识到原来R语言绘图可以这么简单美观,这可是为R语言争取了不少用户,因为觉得在数据处理不够便捷,大神就写了一个目前堪称数据处理的神器tidyverse,将众多的方法串联到一起,tidyverse是他把自己所写的包整理成了一整套数据处理的方法,包括ggplot2、readr、purrr、dplyr、tidyr、stringr、forcats、reshape2等。同时还专门写了一本书《R for Data Science》,中文书名是《R数据科学》。这本书里面也详细介绍了tidyverse的使用方法。这个大佬目前是Rstudio首席科学家,中国R语言的荣光谢益辉大神也在这个公司工作。而在这里,我们主要介绍R语言的stringr包。

定义和举例

正则表达式是什么?它是一种提取文本串特征、描述文本串的方法!

  • 举个例子,假如我想提取字符串的"Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"中的"Chlamydomonas""IFT80"
  • 然后,我观察它们的共同特征,发现它们都是位于括号内
  • "Chlamydomonas"这个字符串主要由大写英文字母小写英文字母组成。
  • "IFT80"主要由大写英文字母数字组成。
  • 归纳一下,"Chlamydomonas"和"IFT80"这两个字符串的共同特征:1. 都位于括号内;2. 都是由大写英文字母、小写英文字母和数字这三部分中的任意两个组成。
  • 因此,我们可以使用\\([A-Za-z0-9]*\\)来代表这两个字符串。
  • 为什么是\\([A-Za-z0-9]*\\)
  • 建议你先浏览完下面的内容再返回来观看,可能理解会更加深刻一点!
  1. 首先,我们想要查找的两个字符串刚好位于括号内。
  • 我们先把括号作为一种匹配的特征,这样可以更精准地找到我们想要的字符串。因为括号是元字符,需要斜杠来转译,而斜杠也是元字符,需要另外一个斜杠来转译。因此,括号的表示模式可以写成这个样子:
pattern = "\\(\\),"
  1. 找到了括号,这个括号里面是要有东西的,内容就是大写英文字母、小写英文字母和数字,所以我们用[A-Za-z0-9]代替。A-Z代表从A-Z的大写英文字母集合,a-z代表从a-z的小写英文字母集合。0-9代表从0-9的数字的集合。
  2. 此外,括号内的内容是大写英文字母、小写英文字母和数字中的任意两部分且数量不限,所以我们用*符号代替。*代表0或者多个。
  • 因此,括号内的表达模式可以写成这样:
pattern = "\\([A-Za-z0-9]*\\),"
  • 现在,我们使用str_match函数来实际操作一下
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> string
[1] "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> pattern <- "\\([A-Za-z0-9]*\\)"
> pattern
[1] "\\([A-Za-z0-9]*\\)"
> str_match(string,pattern)
     [,1]             
[1,] "(Chlamydomonas)"
> str_match_all(string,pattern)
[[1]]
     [,1]             
[1,] "(Chlamydomonas)"
[2,] "(IFT80)"        
  • 我们发现,str_match只返回匹配到的字符串的第一个,但str_match_all可以返回所有匹配到的字符串。
  • 但即使是str_match_all,我们也发现返回的两个字符串,都是带着括号的。但我们最终结果并不想包含括号,那我们需要怎么做
  • 通常的处理方法,是使用str_remove_all函数去除括号,具体演示如下:
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> pattern <- "\\([A-Za-z0-9]*\\)"
> a <- str_match_all(string,pattern) # str_match_all函数输出结果是列表
> pattern <- "\\(|\\)"
> str_remove_all(a[[1]], pattern)
[1] "Chlamydomonas" "IFT80"        
  • 但通过?str_match查询到了,我们发现了一个更简单高效的方式:

For str_match, a character matrix. First column is the complete match, followed by one column for each capture group. For str_match_all, a list of character matrices.

  • str_match函数会返回完整匹配的第一列,也会返回完整匹配中的捕获组
  • 什么是捕获组?正则表达式分组分为捕获组(Capturing Groups)非捕获组(Non-Capturing Groups)当你把一个正则表达式用一对小括号包起来的时候,就形成了一个捕获组,如(\d)表示一个分组,(\d)(\d)表示有两个分组,(\d)(\d)(\d)表示有三个分组,有几对小括号元字符组成,就表示有几个分组,以此类推。
  • 在我们的例子中,我们想要把括号中的内容[A-Za-z0-9]*单独提取出来,那么需要给它增加一对括号,形成一个捕获组
> pattern = "\\([A-Za-z0-9]*\\)"
> pattern2 = "\\(([A-Za-z0-9]*)\\)"
> str_match_all(string,pattern2)
[[1]]
     [,1]              [,2]           
[1,] "(Chlamydomonas)" "Chlamydomonas"
[2,] "(IFT80)"         "IFT80"        
> str_match_all(string,pattern2)[[1]][,2]
[1] "Chlamydomonas" "IFT80"

正则表达式

①.R中的正则表达式模式有三种:

1、扩展正则表达式:默认方式(第一种是最常用的);
2、Perl风格正则表达式:设置参数perl = TRUE;
3、字面意义正则表达式:设置参数fixed = TRUE。

②.R中的基本元字符如下:(这些字符的含义与Python一样)

. \ | ( ) [ ] ^ $ * + ?

.     表示任意字符,包括换行符;
\     表示对字符进行转义,即恢复它本来的含义。但在R中,\中也是字符,所以转义\是要用\\;
|     表示匹配,举个例子,A|B,表示对A或B其中一个匹配,A匹配成功则不匹配B;
()    字符组,括号中的模式作为一个整体进行匹配
[]    字符集合,括号内的任意字符将被匹配
^     匹配字符串开头。举个例子,^MT-表示匹配开头含有M、T这两个字母的字符串(常见于单细胞测序中线粒体基因的匹配)。但如果加了[]并且位于首位,则表示反义。例如[^6],则表示匹配所有不是6的字符
$     匹配字符串结尾。但将它置于[]内则消除了它的特殊含义。例如[akm$],表示匹配’a’,’k’,’m’或者’$’。

数量词:* + ? {m} {m,n} {m,}

*      前一个规则匹配0或无限次
+      前一个规则匹配1或无限次
?      前一个规则匹配0或1次,也常用语非贪婪模式中
{m}    前一个规则匹配m次
{m,n}  前一个规则匹配m~n次,尽可能多
{m,}   前一个规则匹配m次以上,尽可能多
③.R中的转义

如果我们想查找元字符本身,如?*,我们需要提前告诉编译系统,取消这些字符的特殊含义。这个时候,就需要用到转义字符\,即使用\?\.当然,如果我们要找的是\,则使用\\进行匹配。

④.R中预定义的字符组
代码 含义说明
[:digit:] 数字:0-9
[:lower:] 小写字母:a-z
[:upper:] 大写字母:A-Z
[:alpha:] 字母:a-z及A-Z
[:alnum:] 所有字母及数字
[:punct:] 标点符号,如. , ;
[:graph:] Graphical characters,即[:alnum:]和[:punct:]
[:blank:] 空字符,即:Space和Tab
[:space:] Space,Tab,newline,及其他space characters
[:print:] 可打印的字符,即:[:alnum:],[:punct:]和[:space:]
⑤.R中代表字符组的特殊符号
代码 含义说明
\w 字符串,等价于[:alnum:]
\W 非字符串,等价于[^[:alnum:]]
\s 空格字符,等价于[:blank:]
\S 非空格字符,等价于[^[:blank:]]
\d 数字,等价于[:digit:]
\D 非数字,等价于[^[:digit:]]
\b Word edge(单词开头或结束的位置)
\B No Word edge(非单词开头或结束的位置)
\< Word beginning(单词开头的位置)
\> Word end(单词结束的位置)

stringr包

①.stringr包安装
#第一种方法是从CRAN上安装发行版:
install.packages("stringr")
#第二种方法是从github上安装最新的版本,可测试最新的功能:
install.packages("devtools")
devtools::install_github("tidyerse/stringr")
#第三种方法是直接安装tidyverse包,它会顺便就把stringr包安装上
install.packages("tidyverse")
②.stringr包函数

stringr包里面的函数主要分为6大类,包括:

  1. 字符串匹配函数:str_detect、str_which、str_count、str_locate、str_locate_all、str_view、str_view_all
  2. 字符串截取函数:str_sub、str_subset、str_extract、str_extract_all、str_match、str_match_all
  3. 字符串长度控制函数:str_length、str_pad、str_trunc、str_trim、str_squish
  4. 字符串变化函数:str_replace、str_replace_all、str_replace_na、str_to_lower、str_to_upper、str_remove、str_remove_all
  5. 字符串拼接/切割函数:str_c、str_dup、str_split、str_split_fixed
  6. 字符串排序函数:str_sort、str_order

接下来,我们将逐个演示这些函数的使用方法。

1. 字符串匹配函数

str_detect可以检测pattern是否包括在某个字符串中,并返回TRUE和FALSE

> x <- c("apple","banana","pear")
> str_detect(x,"a")
[1] TRUE TRUE TRUE

str_count检测pattern是否包括在某个字符串中的数目

> x <- c("apple","banana","pear")
> str_count(x,"a")
[1] 1 3 1

str_which告诉pattern的索引位置

> x <- c("apple","banana","pear")
> str_which(x,"a")
[1] 1 2 3
> str_which(x,"ar")
[1] 3
> str_which(x,"an")
[1] 2
> str_which(x,"ap")
[1] 1

str_locatestr_locate_all返回pattern的开始和终止位置;
区别是str_locate只返回字符串里面的首个匹配到的pattern;
str_locate_all返回字符串里面的所有匹配到的pattern;

> x <- c("apple","banana","pear")
> str_locate(x,"a")
     start end
[1,]     1   1
[2,]     2   2
[3,]     3   3
> str_locate(x,"an")
     start end
[1,]    NA  NA
[2,]     2   3
[3,]    NA  NA
> str_locate_all(x,"a")
[[1]]
     start end
[1,]     1   1

[[2]]
     start end
[1,]     2   2
[2,]     4   4
[3,]     6   6

[[3]]
     start end
[1,]     3   3

> str_locate_all(x,"an")
[[1]]
     start end

[[2]]
     start end
[1,]     2   3
[2,]     4   5

[[3]]
     start end

str_viewstr_view_all函数都可以以可视化的方式,返回字符串中匹配到的pattern;

  • 区别是str_view只返回字符串里面的首个匹配到的pattern;
  • str_view_all返回字符串里面的所有匹配到的pattern;
  • 强烈建议掌握这两个函数,在自己书写正则表达式时,可以清晰地看到字符串有没有被匹配上自己书写的正则表达式
> x <- c("apple","banana","pear")
> str_view(x,"a")
image.png
> x <- c("apple","banana","pear")
> str_view_all(x,"a")
image.png
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> pattern <- "\\([A-Za-z0-9]*\\)"
> str_view_all(string,pattern)
image.png
2. 字符串截取函数

str_sub在给定起始和终止参数的基础上对字符串进行截取或者替换

> x <- c("apple","banana","pear")
> str_sub(x,1,3)
[1] "app" "ban" "pea"
> # 负号表示从后往前数
> str_sub(x,-3,-1)
[1] "ple" "ana" "ear"
> # "a"替换截取出来的字符串,此时原本的x会发生改变
> str_sub(x,1,3) <- "a"
> x
[1] "ale"  "aana" "ar"

str_subset返回pattern所在的字符串

  • 与前面字符串匹配函数函数的区别是:前面的字符串匹配函数,要么返回True或False(例如str_detect)、要么返回数字(例如str_count
> x <- c("apple","banana","pear")
> str_subset(x,"ap")
[1] "apple"
> str_subset(x,"an")
[1] "banana"
> str_subset(x,"a")
[1] "apple"  "banana" "pear"  
># negate = T时,返回不匹配的字符串
> str_subset(x,"ap",negate = T)
[1] "banana" "pear" 

str_extract函数返回每个字符串中首个匹配到的pattern
str_extract_all函数返回每个字符串中所有匹配到的patternstr_extract_all函数中simplify默认为False,默认返回list;当simplify为True,则返回matrix

> x <- c("apple","banana","pear")
> str_extract(x,"a")
[1] "a" "a" "a"
> str_extract_all(x,"a")
[[1]]
[1] "a"

[[2]]
[1] "a" "a" "a"

[[3]]
[1] "a"

> str_extract_all(x,"a",simplify = T)
     [,1] [,2] [,3]
[1,] "a"  ""   ""  
[2,] "a"  "a"  "a" 
[3,] "a"  ""   ""  

str_match函数返回每个字符串中首个匹配到的pattern,以matrix的形式呈现
str_match_all函数返回每个字符串中所有匹配到的pattern,以list的形式呈现

> x <- c("apple","banana","pear")
> str_match(x,"a")
     [,1]
[1,] "a" 
[2,] "a" 
[3,] "a" 
> str_match_all(x,"a")
[[1]]
     [,1]
[1,] "a" 

[[2]]
     [,1]
[1,] "a" 
[2,] "a" 
[3,] "a" 

[[3]]
     [,1]
[1,] "a" 
3. 字符串长度控制函数

str_length函数可以计算字符串的长度

> x <- c("apple","banana","pear")
> str_length(x)
[1] 5 6 4

str_pad函数可以填充字符

  • width控制我们要填充后的字符串的整体长度,如果width比字符串本身要短,它就不会继续填充。谨记,str_pad函数永远不会使字符串更短;
  • side表示填充方向,默认是“left”;
  • pad就是我们要填充什么进去,但是只能指定单个字符;
> str_pad(c("a", "abc", "abcdef"), 10,pad="a")
[1] "aaaaaaaaaa" "aaaaaaaabc" "aaaaabcdef"
> str_pad(c("a", "abc", "abcdef"), 10,pad="k")
[1] "kkkkkkkkka" "kkkkkkkabc" "kkkkabcdef"
> str_pad(c("a", "abc", "abcdef"), 10,side="left",pad="k")
[1] "kkkkkkkkka" "kkkkkkkabc" "kkkkabcdef"
> str_pad(c("a", "abc", "abcdef"), 10,side="right",pad="k")
[1] "akkkkkkkkk" "abckkkkkkk" "abcdefkkkk"
> str_pad(c("a", "abc", "abcdef"), 10,side="both",pad="k")
[1] "kkkkakkkkk" "kkkabckkkk" "kkabcdefkk"
> str_pad(c("a", "abc", "abcdef"), 5,pad="k")
[1] "kkkka"  "kkabc"  "abcdef"
> str_pad(c("a", "abc", "abcdef"), 1,pad="k")
[1] "a"      "abc"    "abcdef"
> str_pad(c("aa", "abc", "abcdef"), 1,pad="k")
[1] "aa"     "abc"    "abcdef"
> str_pad(c("a", "abc", "abcdef"), c(1, 2, 3),pad="k")
[1] "a"      "abc"    "abcdef"
> str_pad(c("a", "abc", "abcdef"), c(2, 4, 7),pad="k")
[1] "ka"      "kabc"    "kabcdef"
> str_pad(c("a", "abc", "abcdef"), c(2, 4, 7),pad=c("k","l","m"))
[1] "ka"      "labc"    "mabcdef"

str_trim函数去除字符串的空白部分

  • side可选择"both", "left", "right",默认是both
> str_trim("  String with trailing and leading white space\t")
[1] "String with trailing and leading white space"
> str_trim("\n\nString with trailing and leading white space\n\n")
[1] "String with trailing and leading white space"

str_squish函数作用和str_trim函数作用一致,但除了去除字符串前、后的空格,它还可以去除字符串中间出现的重复的空格。这一点上,str_trim函数无法办到。

> str_trim("\n\nString with excess,  trailing and leading white   space\n\n")
[1] "String with excess,  trailing and leading white   space"
> str_squish("\n\nString with excess,  trailing and leading white   space\n\n")
[1] "String with excess, trailing and leading white space"

str_trunc函数可以把字符串切割到指定长度

> x <- "This string is moderately long"
> str_trunc(x, 20, "right")
[1] "This string is mo..."
> str_trunc(x, 20, "left")
[1] "...s moderately long"
> str_trunc(x, 20, "center")
[1] "This stri...ely long"
4. 字符串变化函数

str_replace函数可以替换pattern为新的字符,仅限于第一个匹配到的
str_replace_all函数可以替换所有匹配到的pattern
str_replace_na 可以将缺失值替换成‘NA’,这样na.omit函数就无法将缺失值删除了

  • 这个函数很好用,建议重点掌握
> x <- c("apple","banana","pear")
> # 把 a 替换成 k 
> str_replace(x,"a","k")
[1] "kpple"  "bknana" "pekr"  
> str_replace_all(x,"a","k")
[1] "kpple"  "bknknk" "pekr" 

> x <- c(NA, "abc", "def")
> x
[1] NA    "abc" "def"
> is.na(x)
[1]  TRUE FALSE FALSE
> table(is.na(x))
FALSE  TRUE 
    2     1
> na.omit(x)
[1] "abc" "def"
attr(,"na.action")
[1] 1
attr(,"class")
[1] "omit"
> str_replace_na(x)
[1] "NA"  "abc" "def"
> x <- str_replace_na(x)
> x
[1] "NA"  "abc" "def"
> na.omit(x)
[1] "NA"  "abc" "def"

str_replacestr_replace_all函数中,replacement可以用\1, \2中表示模式中的捕获

  • 注意数据中第二个元素因为不能匹配到pattern,所以就原样返回了, 没有进行替换。
> str_replace_all(c("123,456", "011"), 
+                 "([[:digit:]]+),([[:digit:]]+)", "\\2,\\1")
[1] "456,123" "011"

str_to_upper函数可以将小写字母转成大写字母
str_to_lower函数可以将大写字母转成小写字母

> x <- c("apple","banana","pear")
> str_to_upper(x)
[1] "APPLE"  "BANANA" "PEAR"  
> str_to_lower(x)
[1] "apple"  "banana" "pear"

str_remove可以移除字符串中首个匹配到的pattern
str_remove_all可以移除字符串中所有匹配到的pattern

> fruits <- c("one apple", "two pears", "three bananas")
> str_remove(fruits, "[aeiou]")
[1] "ne apple"     "tw pears"     "thre bananas"
> str_remove_all(fruits, "[aeiou]")
[1] "n ppl"    "tw prs"   "thr bnns"
5. 字符串拼接/切割函数

str_c函数可以拼接多个字符串

  • sep: 把多个小的字符串拼接为多个更大的字符串,sep用于其中字符串的分割
  • collapse: 把多个小的字符串拼接为一个大的字符串,collapse用于其中字符串的分割
> letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u"
[22] "v" "w" "x" "y" "z"
> str_c(letters,letters,sep = "-")
 [1] "a-a" "b-b" "c-c" "d-d" "e-e" "f-f" "g-g" "h-h" "i-i" "j-j" "k-k" "l-l" "m-m" "n-n"
[15] "o-o" "p-p" "q-q" "r-r" "s-s" "t-t" "u-u" "v-v" "w-w" "x-x" "y-y" "z-z"
> str_c(letters,letters,collapse = "-")
[1] "aa-bb-cc-dd-ee-ff-gg-hh-ii-jj-kk-ll-mm-nn-oo-pp-qq-rr-ss-tt-uu-vv-ww-xx-yy-zz"

str_dup函数可以复制字符串

> fruit <- c("apple", "pear", "banana")
> str_dup(fruit, 2)
[1] "appleapple"   "pearpear"     "bananabanana"
> str_dup(fruit, 1:3)
[1] "apple"              "pearpear"           "bananabananabanana"
> str_c("ba", str_dup("na", 0:5))
[1] "ba"           "bana"         "banana"       "bananana"     "banananana"  
[6] "bananananana"

str_split按照pattern分割字符串

  • 当simplify为TRUE时,返回matrix

str_split_fixed按照pattern将字符串分割成指定个数

> fruits <- c(
+     "apples and oranges and pears and bananas",
+     "pineapples and mangos and guavas"
+ )
> 
> str_split(fruits, " and ")
[[1]]
[1] "apples"  "oranges" "pears"   "bananas"

[[2]]
[1] "pineapples" "mangos"     "guavas"    

> str_split(fruits, " and ", simplify = TRUE)
     [,1]         [,2]      [,3]     [,4]     
[1,] "apples"     "oranges" "pears"  "bananas"
[2,] "pineapples" "mangos"  "guavas" ""       
> 
> # Specify n to restrict the number of possible matches
> str_split(fruits, " and ", n = 3)
[[1]]
[1] "apples"            "oranges"           "pears and bananas"

[[2]]
[1] "pineapples" "mangos"     "guavas"    

> str_split(fruits, " and ", n = 2)
[[1]]
[1] "apples"                        "oranges and pears and bananas"

[[2]]
[1] "pineapples"        "mangos and guavas"

> # If n greater than number of pieces, no padding occurs
> str_split(fruits, " and ", n = 5)
[[1]]
[1] "apples"  "oranges" "pears"   "bananas"

[[2]]
[1] "pineapples" "mangos"     "guavas"    

> # Use fixed to return a character matrix
> str_split_fixed(fruits, " and ", 3)
     [,1]         [,2]      [,3]               
[1,] "apples"     "oranges" "pears and bananas"
[2,] "pineapples" "mangos"  "guavas"           
> str_split_fixed(fruits, " and ", 4)
     [,1]         [,2]      [,3]     [,4]     
[1,] "apples"     "oranges" "pears"  "bananas"
[2,] "pineapples" "mangos"  "guavas" ""       
6. 字符串排序函数

str_order函数和str_sort函数都可以对字符串进行排序,两者之前的区别在于前者返回排序后的索引(下标),而后者返回排序后的实际值

  • decreasing:排序方式,默认为False,即升序;
> x <- c("a", "cc", "bbb", "dddd")
> str_sort(x)
[1] "a"    "bbb"  "cc"   "dddd"
> str_order(x)
[1] 1 3 2 4
stringr重要函数总结
  • stringr包里面有很多函数,但许多函数我们平时使用率其实不高
  • 为了提高学习的性价比,我列举了自己平时学习过程中使用到频率最高的几个stringr函数。相信掌握了这些高频率的重要函数,你可以更游刃有余地应付日常R语言工作中关于处理字符串的需求。
字符串匹配函数:str_detect、str_which、str_view、str_view_all
字符串截取函数:str_subset、str_extract、str_extract_all、str_match、str_match_all
字符串变化函数:str_replace、str_replace_all、str_remove、str_remove_all
字符串拼接/切割函数:str_c、str_split、str_split_fixed
  • 以表格形式总结如下:
函数 功能说明 R Base中对应函数 是否允许正则表达式
str_detect 检测pattern是否包括在某个字符串中 grepl
str_which 告诉pattern的索引位置
str_view 可视化字符串中首个pattern匹配到的位置
str_view_all 可视化字符串中所有pattern匹配到的位置
str_subset 返回pattern所在的字符串
str_extract 返回每个字符串中首个匹配到的pattern regmatches
str_extract_all 返回每个字符串中所有匹配到的pattern regmatches
str_match 返回每个字符串中首个匹配到的pattern
str_match_all 返回每个字符串中所有匹配到的pattern
str_replace 替换每个字符串首个匹配到的pattern sub
str_replace_all 替换每个字符串所有匹配到的pattern gsub
str_remove 移除字符串中首个匹配到的pattern
str_remove_all 移除字符串中所有匹配到的pattern
str_c 可以拼接多个字符串 paste或paste0
str_split 按照pattern分割字符串 strsplit
str_split_fixed 按照pattern将字符串分割成指定个数
  • 最后,我们再回到文章最开头的例子。
  • 假如我想提取字符串的"Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"中的"Chlamydomonas""IFT80"
  • 文章开头使用的是str_match_all函数.
  • 但当你学习完以上内容,相信你心中已经有其他的解法:
  1. 例如,使用str_split函数可以顺利将括号内的东西提取出来
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> str_split(string,"\\(|\\)",simplify = T)
     [,1]                                                [,2]            [,3] [,4]   
[1,] "Homo sapiens intraflagellar transport 80 homolog " "Chlamydomonas" " "  "IFT80"
     [,5]    
[1,] ", mRNA"
> str_split(string,"\\(|\\)",simplify = T)[,c(2,4)]
[1] "Chlamydomonas" "IFT80"        
  1. 例如,使用str_exact函数和str_remove_all函数可以顺利将括号内的东西提取出来
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> str_extract_all(string,"\\([A-Za-z0-9]*\\)")
[[1]]
[1] "(Chlamydomonas)" "(IFT80)"
> a <- str_extract_all(string,"\\([A-Za-z0-9]*\\)")
> str_remove_all(a[[1]], pattern)
[1] "Chlamydomonas" "IFT80"        
  1. 你甚至可以用srt_replace_all函数提取括号内的字符
> string <- "Homo sapiens intraflagellar transport 80 homolog (Chlamydomonas) (IFT80), mRNA"
> pattern <- "([:print:]+)(\\()([:print:]+)(\\))([:print:]+)(\\()([:print:]+)(\\))([:print:]+)"
> str_replace_all(string, pattern,"\\3")
[1] "Chlamydomonas"
> str_replace_all(string, pattern,"\\7")
[1] "IFT80"
  • 但我个人的建议是,正则表达式不要写得太花里胡哨。
  • 对于初学者来说,正则表达式写得越长越容易出错。
  • 个人建议,初学者尽量从简单出发,只要最后能达到你想要的目的,比如说将特定字符串提取出来,哪怕中间过程多用几个stringr的函数,也是值得鼓励的。
参考:

R 正则表达式
R语言与正则表达式
原来是它!正则表达式揪出生信分析中没有报错的内鬼错误
R语言教程
R for Data Science

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容