主讲老师第二十一课:正则表达式
关于正则表达式(正则表达式.zip),虽然说传的神乎其神,但是理解后很好用,而且这个正则表达式,前后经历了十来年。我们在 word 文档或者 excel 中,经常使用查找和替换,然而有些情况,word 是解决不了的,举个例子,条件搜索,统计文中,前面有 “data,” “computer” or “statistical” 的 “analysis”,这个单词的个数,找出文中重复的单词,比如“we love love you”,拼写检查,检查电话号码(邮件,密码等)是否正确格式,检查日期书写的规范与统一,提取信息,以及文本挖掘等等。再举个大家比较熟悉的例子,比如我们要在一段 mRNA 序列里查找起始密码子“ATG”的位置,在 word 中使用查找就可以,也可以使用快捷键 Ctrl+F ,输入 ATG 就行,这是常规操作,大家基本都会,但是如果我们要寻找一段CDS区(蛋白编码序列)来看下 CDS 的特征,通常是以 ATG 起始,以 TGA , TAG , TAA 三个中的任意一个结尾,起始和终止中间出现的字符要是 3 的倍数(三联密码子),然而,上述描述的规律无法直接输入,这
时就需要用一个通用的具有代表性式子来表示,比如说:
这个表达式就称之为正则表达式,Regular Expression,这是一个强大、便捷、高效的文本处理工具。
那么,什么是正则表达式呢?简单点说,正则表达式是处理字符串的,复杂点说,正则表达式描述了一种字符串匹配的模式(pattern),通常被用来检索、替换那些符合某个模式(规则)的文本,这种固定的格式的文本,生活中常见的包括电话号码、网络地址、邮件地址和日期格式等等。然而,正则表达式并不是 R 语言特有的,事实上,几乎所有程序语言都支持正则表达式,比如说,Perl, Python, Java 等等都支持正则表达式。R 语言中很多函数都需要使用正则表达式,然而正则表达式不太好学,幸运的是,大神 Hadley Wickham开发的 stringr 包让正则表达式简单易懂,下面,我们来看下正则表达式与 stringr 包的使用
1.R 包的安装与读取
由于 stringr 包不会一直处理文本数据,所以 stringr 包不属于 tidyverse 包的核心包,因此,在需要使用时我们可以通过命令来加载它,同时,运用前面学过的字符型变量的知识, 我们创建一个包含了不同内容的字符串用于后续的使用。
正则表达式的匹配模式用 pattern 来表示,他把正则表达式在字符串的功能分为四个方面:
1.查找:确定这个模式有没有;
2.定位: 返回模式起止位置;
3.取回:返回模式匹配到的条目;
4.替换:替换匹配的模式,返回替换后的结果。分别是 Detect pattern,Locate pattern,Extract
pattern,以及 Replace pattern。接着,我们将逐个讲解一些常用的函数使用方法。
2.正则表达式中的三个括号
在这里先介绍正则表达式中的三个括号
1.中括号 [] 表示选项,代表内部数据任意选择,举个例子,比如[ATCG],表示 A,T,C, G 四个字符
随意选择,如果是数字也是一个意思,[1356],表示有 1,3,5,6 这个四个选项,当然,如果嫌麻烦,也可以用 - 连接起始代表范围,比如[A-Z],代表大写的 26 个字母,[a-z],代表小写的 26 个字母,[0-9],代表从 0 到 9 的 10 个数字,此外,还可以混写,[0-9a-zA-Z],代表所有的数字和字母
2.大括号 {} 代表重复次数,比如[ATCG]{3},表示从 A,T,C,G 四个字符中选择 3 个,那么这时候会产生
ATC , ATG , ACG , TCG 4 种组合,也就是所说的三联密码子,如果是两个数,用逗号隔开,代表范围,[0-9]{4,10} 表示产生 4 位数到 10 位数都可以,而如果两个数中的第二个缺失,比如[0-9]{4,},代表 4 位数及以上。
3.圆括号 () 代表成组,即表示分组,分组,是其中正则表达式的核心功能
了解了理论知识后,我们来看下具体的例子,不过,提前说一下,学了这三个符号以后,特别是[],别和前面的取子集又搞成一团了,我们根据上面字符型变量中的几个电话号码,来生成一个能够匹配他们的表达模式pattern。
首先,观察一下两个电话号码, 579-499-7527 和 543.355.3679 ,分别由三串数字组成,且中间通过 -或者 . 来进行连接,找到了规律后,我们就可以开始正式构建表达式一开始看可能有些眼花缭乱,我们来进行拆解一下,根据 () 表示分组的功能,我们以 () 为单位进行拆分。
逐个讲解一下,第一个, [1-9][0-9]{2} ,这表示有三个数字,第一个数字不为零,后两位数字从 0-9中任取两个,接着,第二和三个表达式中, [0-9]{3} 和 [0-9]{4} 分别表示 3 位数和四位数,其中,这三个大的表达式之间用 [- .] 来间隔,分别是 - 和 . 号,再回过头去看下这个表达式,是不是和蔼可亲多了呢?
3.str_view 函数的使用
表达模式会构建以后,我们通过 str_view() 函数来展示正则表达式的应用。
经过匹配,最终得到以下的结果形式。
另外,注意一点,在匹配过程中,当一个字符变量中存在多个匹配结果时,默认返回第一个匹配结果,比如说,上面的第四个变量,只显示第一个匹配结果,随后,我们分别根据前面提到的查找、定位、取回和替换四个功能,来分别介绍对应的几个函数的使用方法。
3.1 查找
首先,在查找中,我们介绍一下 str_detect() 函数,从字符串 strings 中检测能否和 pattern匹配,其返回的结果是逻辑值变量。
结果显示,第 2,3,4 个字符变量匹配到了结果
3.2 定位
使用 str_locate() 函数,可以从字符串 strings 中检测能否和 pattern 匹配,返回匹配的起止位置。
3.3 取回
在取回过程中,分为两个不同的情况:
1).使用 str_subset() 函数返回经过匹配得到的原始条目内容2).使用 str_extract() 函数返回的是匹配到的模式内容3).使用 str_match() 函数返回的是一个数据框,在该数据框中,第一列是匹配到的模式内容数据,后面依次是括号中的内容,模式中有多少个 () ,就返回多少列由于本例中有三对小括号,因此一共是 4 列内容。
3.4 替换
使用 str_replace() 函数从 strings 中能够精确匹配 pattern 的内容,并替换为新的内容。
将所有匹配到的内容替换成 XXX-XXX-XXXX。
4.正则表达式中其他相关知识点
4.1 锚点
在默认情况下,正则表达式会匹配字符串中的任意部分,然而,有时候,我们需要一些特定符号的帮助,即所谓的锚点,以使得 R 能从字符串的开头或者结尾处进行匹配:
(1). ^从字符串开头进行匹配;(2). $从字符串结尾进行匹配。
甚至,我们可以同时使用^和$两个符号,来对一个完整的字符串进行精准的匹配。
4.2 表示次数的符号
学会了三个括号以后,接下来,介绍一下另外三个在正则表达式中常用的表示匹配次数的符号。
分别介绍一下三个符号的使用方法:
(1). ?表示 0 次或 1 次;(2). +表示 1 次或多次;(3). *表示 0 次或多次;
再回过头来看下前面最开始提到的内容:
首先是以起始密码子 ATG 开头,接着出现三联密码子,用 [ATCG]{3} , 出现的次数是 1次或者多次,所以整体给个加号 + ,因此得到, ATG([ATCG]{3})+ ,接着要出现终止密码子,有三种,分别是TGA , `TGA , TAA ,正则表达式中竖线 | 表示或的意思,那么 (TGA|TAG|TAA) 就代表,三个终止密码子任意选择一个。接下来,看几个例子当然,我们也可以控制匹配的次数。
5.转义符号
此外,最后还有一个知识点:如果一个字符串出现以下的符号,该怎么匹配?
这些字符我们都已经碰到过,他们比较特别,因为他们除了字符串本身外,还有其他意义,正常情况下出现的时候都是特殊意义。如果想要他代表字符本身的意思,比如点号 . 就代表点号,就需要给他转义,转义的符号是斜杠 \ ,那么点号是不是就应该写为 \. ?
但是,并非如此,这里的斜杠 \ 也属于元字符,需要另外一个斜杠来转义。那么在 R 语言中,如果想要表示匹配点号本身,就应该是这个样子的 \\. 。那么如果特殊一点我要匹配一对括号怎么办?括号也是元字符,那就得转义 \\(\\) 。如果要匹配两个 // ,那就应该写成 \\/\\/ ,十分有趣吧?来看个例子,如果我们想要使用 str_split() 函数进行切分,同时按照点号 . 来切分。
这种情况下结果是这样的,显然不对,因此,点号应该用转义符号去转义。
这样,关于正则表达式的基本内容就先介绍到这里了。