R语言正则表达式

R语言正则表达式

正则表达式详解来源:dearchao, Gloria Li and Jenny Bryan https://www.360docs.net/doc/0e15188295.html, 编译:思亮

R语言中字符串的匹配替换是字符串操作的常见工作,正则表达式用于描述文本的拼写规则,这些规则用于我们的匹配,替换等操作中。本文介绍R中正则表达式的基本常见用法

入门和相关函数

了解正则表达式的童鞋们,看完本文后,可以什么都不记得,但是我要说的是,对于更为深入理解正则表达式,需要结合各种情况多练习,方能熟练应用。一句话,“我亦无他,唯手熟尔”,同样适用于学习R语言的其他相关技术。

正则表达式相关的函数主要有grep,grepl,sub,gsub等,用于匹配或者替换。下面给出一个简单的例子来理解正则表达式是搞嘛的。我要在如下的字符串中寻找包含了单词hi的字符串

charvec<-c('hit','shi','hi','chip','Hi','HI','hI','hi, girl','Li: hi,', 'hi美女')

grep('hi',charvec)

## [1] 1 2 3 4 8 9 10

可以看到,包含了hi的所有字符都会被匹配上,似乎并不包含大小写,或者不管字符串是否为一个单词。现在看我们的问题似乎没有那么简单,我们的任务是匹配包含了hi这个单词的字符串。这里,\b是正则表达式中匹配单词边界,虽然单词分界一般用的是空格,标点符号,但\b匹配的不是单词的某个分隔符号,而是一个位置,记住它是一个位置,是个空的字符。

准确地讲,\b匹配一个位置,该位置前一个和后一个字符不都是当前区域语言环境下的字母,数字,下划线。也就是说,单词的分界位置前后不能都是字母、数字和下划线。这个描述是不是很抽象?我觉得也是,理解它花了好久,好久,好久。

grep('\\bhi\\b',charvec)

## [1] 3 8 9

上面的代码让我们直观知道了何为正则表达式下面就根据不同表达式的应用场合来论述。

字母和数字

我们已经知道的一些字符有\b,还有其他常用的一些表达式,我们称为元字符。

?\d 数字0,1,2,3,...,9

?\w 单词,指当前区域语言的字母、数字和下划线。如果是中文区域语言,汉字也是单词。

?\b 单词的开始或结束位置

?[:digit:] 数字0~9

?[:alpha:] 当前区域语言的字母

?[:alnum:] 当前区域语言的字母和数字

?[:lower:] 当前区域语言小写字母

?[:upper:] 当前区域语言大写字母

?[a-z] 小写英文字母a~z

?[A-Z] 大写英文字母A~Z

?[A-z] 所有大小写英文字母

charvec<-c('-',',','。','word','10','单词','にほんご','精確')

grep('\\w',charvec,value=T)#找出所有包含了单词的字符,注意这里单词包含了字母

## [1] "word" "10" "单词" "にほんご" "精確"

grep('[[:alpha:]]',charvec,value=T)#同上

## [1] "word" "单词" "にほんご" "精確"

grep('[a-z]',charvec,value=T)#找到包含小写英文字母的字符

## [1] "word"

开始与结束

虽然\b给出了对应的单词边界位置,但是有时我们需要明确开始和结束位置。下面介绍开始和结束的情况。

?^ 字符串的开始位置

?$ 字符串的结束位置

当我们掌握了若干个正则表达式做法时,组合在一起就会产生奇妙的化学反应。

charvec<-c('about','book','word', 'this is a book')

grep('\\bb',charvec,value=T)#找到包含了b开头单词的字符串

## [1] "book" "this is a book"

grep('^b',charvec,value=T)#找到仅以b开头的字符串

## [1] "book"

grep('^b.*k$',charvec,value=T)#找到以b开头,k结尾的字符串

## [1] "book"

最后的代码中用到了重复*和.,下面讲讲重复

重复

重复是经常和其他正则表达式的元字符配合使用的一类

?. 除了换行符\n以外的任意字符

?? 前面的项目重复最多一次

?* 前面的项目重复了0次或者多次

?+ 前面的项目重复了1次或更多次

?{n} 前面的项目重复了n次

?{n,} 前面的项目重复了n次或更多次

?{n,m} 前面了项目重复了至少n次,不多于m次

charvec<-c('oh','ohhh','ohh', 'oohhhhh, my god','ohho')

grep('oh{2}',charvec,value=T)#找到ohh

## [1] "ohhh" "ohh" "oohhhhh, my god" "ohho"

上述代码找到了包含ohh的字符串,但是如果我想要的是ohh后面没有h,或者是已经结束了,怎么办。

grep('oh{2}([^h]|\\b)',charvec,value=T)#找到ohh,后面没有字符或者非h的字符

## [1] "ohh" "ohho"

反义

有的时候我们需要查找不属于某个定义的字符,这时就需要反义。反义就是\+大写字母这种形式。

?\W 不是单词的字符

?\D 不是数字的字符

?\B 不是单词分界位置的位置,这个描述好晦涩

?[^x] 不是x的字符

?[^abo] 除了abo以外的任意字符

charvec<-c('007','a1','a2', 'b3','cc')

grep('\\D',charvec,value=T)#找到包含非数字字符的字符串

## [1] "a1" "a2" "b3" "cc"

grep('[^ab]',charvec,value=T)#找到包含除了ab以外还有其他字符的字符串

## [1] "007" "a1" "a2" "b3" "cc"

特殊符号

通过上文我们知道,如^ $ [ ] 这类含有特殊意义的符号如果包含在字符串里我们怎

么匹配?\符号为转义字符,我们在使用这些符号时,前面+\\即可。

charvec<-c("i'm Lufy",'hello world','symbol[', '^','')

grep("\\^",charvec,value=T)#找到包含^字符的字符串

## [1] "^"

分组与分支条件

我们有时需要用分支条件来匹配某个位置,用|来分隔不同条件单元。有时需要将

多个元字符组成一个整体单元(item)来匹配。如ab作为一个整体,好了,看看

例子吧。

charvec<-c("i'm Lufy",'I am Lufy','He is Lufy')

grep("('m|am)",charvec)#找到包含'm或am字符的字符串,这里用到了分支

## [1] 1 2

charvec<-c("288",'189********','no, no, no')

grep("(no, ){2, }",charvec)#找到包含no, 并重复了2次及其以上字符

## [1] 3

后向引用

我们使用小括号分组了字符为若干个项目后,需要匹配这个文本做后续处理。默认情况下,每个分组会有一个默认组号,规则为从左到右,第一个分组组号为1,第

二个为2,依次类推。

后向引用用于重复搜索前面某个分组匹配的文本。例如,代表分组1匹配的文本。难以理解?请看示例:

charvec<-c("ws80m",'ws10m','ws30m')

gsub("ws(\\d+)m",'\\1',charvec)#将上述字符串中的数字部分用小括号分组,组号是1,并后向引用。这样就把上述字符中数字部分提取出来了。

## [1] "80" "10" "30"

其他未尽事宜

上述的正则表达式的使用过程大家熟悉以后,就可以尝试做一些工作了。当然,我承认其中有些没有讲到的东西,如零宽断言,负向零宽断言,注释,贪婪与懒惰,平衡组递归匹配等等。这些内容笔者也不常用,大家用到时候再百度即可。

总结

至此,有关R的正则表达式介绍的差不多了。剩下的就是各位读者朋友小试牛刀自行体会的时候了,还是那句话,多做代码,练习,练习,练习,重要事情说3遍,任何脱离实践的东西都是纸上谈兵。好了,今天就写这么多,后续更新敬请期待。

相关文档
最新文档