R中的正则表达式

时间:2020-02-23 14:43:54  来源:igfitidea点击:

R或者regex中的正则表达式是一系列特殊字符,它们被定义为与文本中的特定搜索模式匹配。
可以出于多种目的创建正则表达式,例如标识数字序列,格式化地址,特殊字符串,部分名称等。

在基于Linux的系统中,总是使用grep命令来计算和搜索正则表达式。
R编程还支持名为grep()的函数来完成这些任务,我们将在以下各节中看到。

R中的正则表达式的组成部分

正则表达式由一些特殊字符和符号组成,这些字符和符号增加了我们正在寻找的搜索模式的含义。
尽管存在与任何搜索字符串匹配的符号,但了解一些经常出现的符号和字符将很有帮助。
这些在下面列出。

  • 点(。
    )–匹配除换行以外的任何字符。

  • 管道(|)–用于在表达式上指定替代或者条件。

  • 方括号[] –方括号中列出的所有字符均应匹配。

  • 连字符(-)–用于指定字符范围,如" [a-m]"或者" [A-Z]"中一样。

  • 大写(^)–用于指定要排除的字符,如[^ 0-9]表示不应该匹配任何数字。

除此之外,我们还需要称为锚的符号来构造正则表达式。
锚是与单词或者字符串的开头或者结尾匹配的字符。
他们是:

  • Cap(^)–匹配字符串的开头。

  • Dollar($)–匹配字符串的结尾。

  • \ <–匹配单词的开头

  • > –匹配单词的结尾。

很多时候,您还需要指定需要匹配的出现次数。
例如,电话号码可能是包含10位数字的字符串。
通过使用称为量词的符号来完成对出现次数的指定。
这些是:

  • 星号(*)–匹配给定的图案至少0次。

  • 加号(+)–至少匹配给定模式1次。

  • 问号(?)–完全匹配一次模式。

  • {n} –完全匹配给定的模式n次。

  • {n,} –匹配图案至少n次。

  • {,n} –最多匹配n次模式。

  • {n,m} –匹配至少出现n次且最多m次的模式。

有时将搜索模式中的字符分为几类,以便于阅读。
每个字符类都有一个代表符号,可用于匹配属于该类的大量字符。
其中一些是:

  • \ d –代表一个数字,\ D代表一个非数字。

  • \ w代表字母数字字符,而\ W代表非字母数字字符。

  • \ x代表十六进制数字。

  • \ s用于空格,\ S用于非空格。

最后,当我们想在正则表达式中匹配这些特殊字符中的任何特殊字符时,必须对它们进行转义。
例如,点已经在正则表达式中带有含义,但是如果您想实际匹配字符串中的点,则必须在字符前面加上反斜杠,例如–\.

R中的正则表达式示例

现在我们知道R中的正则表达式的组成部分,因此可以在一些示例中使用它们。

  • ^ The –匹配所有以单词The开头的句子。

  • boat $–匹配所有以boat结尾的句子。

  • ^ The。

  • boat $–匹配所有以The开头,包含零个或者多个其他字符并以boat结尾的句子。
  • ab * c –匹配模式ac,abc,abbc,abbbc,abbbbbc ..etc

  • ab + c –匹配模式abc,abbc,abbbc,abbbbc…等。

  • \ d {3} -\ d {4} –将所有匹配项与三个数字字符,一个连字符和四个数字字符相匹配,例如– 456-1223或者222-7658,依此类推。

  • a….. –匹配所有以小写字母a开头的六个字母的单词。

  • [^ anc]。

  • –匹配长度至少为2且不以a,n或者c开头的任何字符串。

因此,可以为要匹配的任何模式字符串构造一个正则表达式。

R中的grep()函数

grep函数将模式与文本匹配,并返回匹配模式的位置。
grep函数具有多个签名,这些签名以不同的方式返回搜索结果。

首先,我们创建一个长字符串矢量来搜索所需的模式。

> strvec <- c("Beamite", "Gazelow", "Gazairy", "Pantheon", "Chimeton", "Sandite", "Zebrawl", "Barrazel", "Bellibou", "Sandapi" )

这是一些随机生成的幻想角色名称的列表。
让我们开始在此向量上使用grep函数。

#Get the indexes of all the names in the list starting with B
> grep("B.*",strvec)
[1] 1 8 9

相反,如果我们希望获取名称而不是索引,则只需在grep函数中添加value = TRUE参数。

> grep("B.*",strvec, value=TRUE)
[1] "Beamite"  "Barrazel" "Bellibou"

同样,如果您希望检查模式是否与字符串向量的每个元素匹配,则可以使用" grepl"函数代替grep。

假设我们希望知道其中一个名称正好是7个字符长,我们编写以下正则表达式,并将其作为模式提供给下面的grepl函数。

> grepl("^(.){7}$", strvec )
 [1]  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE

处理R中正则表达式的其他函数

如果您想在字符串中实际定位模式,则使用regexp()函数。
此函数还返回匹配的模式首次出现的长度。

> regexpr("ite$",strvec)
 [1]  5 -1 -1 -1 -1  5 -1 -1 -1 -1
attr(,"match.length")
 [1]  3 -1 -1 -1 -1  3 -1 -1 -1 -1
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE

我们正在此处搜索所有以" ite"结尾的字符串。
字符串向量的第一个和第六个元素以此结尾。
因此,对于每个位置,位置被描绘为5。

如果没有出现该模式,则该函数返回-1。
函数结果的下一部分还返回匹配的字符串的长度,在当前情况下为3。

如果您希望检索匹配的子模式,而不是位置,则使用的函数是regmatches()

> regmatches(strvec,regexpr("S.*", strvec) )
[1] "Sandite" "Sandapi"

此函数使用regexp()函数获取要匹配的位置,并获取与表达式匹配的字符串。

最后,如果您想匹配一个字符串并用新的模式替换它,那么sub()就是您要使用的函数。
假设我们希望在字符串向量中将所有B都更改为D。
我们可以通过以下方式做到这一点。

> sub("[Bb]","D",strvec)
 [1] "Deamite"  "Gazelow"  "Gazairy"  "Pantheon" "Chimeton" "Sandite"  "ZeDrawl" 
 [8] "Darrazel" "Dellibou" "Sandapi"

请注意,子功能仅替换了第一次出现的图案。
以前是" Bellibou"的字符串现在变成了" Dellibou"。
相反,要替换所有出现的字母,我们使用gsub()函数,g表示全局替换。

> gsub("[Bb]","D",strvec)
 [1] "Deamite"  "Gazelow"  "Gazairy"  "Pantheon" "Chimeton" "Sandite"  "ZeDrawl" 
 [8] "Darrazel" "DelliDou" "Sandapi"