base | 文本处理方法(Ⅰ-2):正则表达式

上篇介绍了stringr工具包的一些字符串处理函数。实际上,str_*()系列的多数函数都经常会使用到正则表达式(regular expression)来进行模式匹配。因此在介绍这些函数之前,本篇先来介绍正则表达式。详见base工具包的regex

library(stringr)

转义符

正则表达式的特点是“所写非所见”,而转义符的作用就是强制使“所写即所见”。转义符使用反斜杠\表示。

例1

书写字符串时需要在首尾加上双引号""或单引号'',但是字符串的内容本身是不包括这些引号的。因此,想要得到一个包含引号的字符串字符串",通过书写以下代码会出现报错:

x <- "字符串""
  • 引号在字符串中有特殊的功能,即作为字符串开始和结束的标志;当引号第二次出现时也意味着字符串的结束,其后不能再有其他内容;

  • 上面代码中,作为字符串内容的引号会被视为字符串结束的标志,而原本作为结束标志的引号反而变得多余,因此报错。

解决办法是在作为字符串内容的引号前加上转义符\

x <- "字符串\""
x
## [1] "字符串\""

par(plt = c(0.05,0.95,0,1), ps = 20, adj = 0,
    family = "mono")
plot(1:6, type = "n", axes = F, ann = F)
text(1,3, labels = x)
  • 虽然在R的输出界面上还可以看到字符串内包含转义符;但作为文本打印在图片上时,转义符不会出现。

例2

反斜杠\作为转义符,那么如何在字符串内包含反斜杠呢?

转义符同样可以转义自身,因此使用两个反斜杠\\即可使字符串内包含一个反斜杠。

x <- "字符串\\"
x
## [1] "字符串\\"

par(plt = c(0.05,0.95,0,1), ps = 20, adj = 0,
    family = "mono")
plot(1:6, type = "n", axes = F, ann = F)
text(1,3, labels = x)
  • 两个反斜杠含义不同:第一个反斜杠表示转义符,第二个反斜杠仅表示一种待转义的特殊符号;

  • 如果想要包含两个连续的反斜杠,需要使用四个反斜杠;以此类推。

电脑中的文件夹地址一般也使用反斜杠来间隔,但由于反斜杠本身又是转义符,因此在R中输入文件地址时需要使用双反斜杠或单正斜杠:

## 错误
setwd("C:\Usere"
## 正确
setwd("C:\\Usere")
## 正确
setwd("C:/Usere")

换行符

在word中当超过一行容量时会自动换行,需要换段时可以按Enter键;而在纯文本格式的文件中,这些操作都需要使用字符来记录。换行符对应的正则表达式是\n

x <- "字符\n串"
par(plt = c(0.05,0.95,0,1), ps = 20, adj = 0,
    family = "mono")
plot(1:6, type = "n", axes = F, ann = F)
text(1,3, labels = x)

同样,想要在字符串中包含符号\n本身,也可以使用转义符:

x <- "字符\\n串"
par(plt = c(0.05,0.95,0,1), ps = 20, adj = 0,
    family = "mono")
plot(1:6, type = "n", axes = F, ann = F)
text(1,3, labels = x)

定位符

使用模式匹配的str_*()系列函数拥有一个参数pattern,它们通常使用匹配符来进行赋值。

定位符属于匹配符的一种,其中^表示字符串的开始;$表示字符串的结束。\b表示文本字符开始或结束的位置,即介于文本字符与非文本字符之间的位置;\B\b的补码,表示介于两个文本字符或两个非文本字符之间的位置。

str_replace_all()函数为例,它可以替换掉字符串中所包含特定模式的部分:

str_replace_all(string, pattern, replacement)
  • pattern:匹配模式;

  • replacement:作为替代的字符。

比如检索单词abstract是否包含字母t的三种情况:

  • 是否包含字母t

  • 是否在开头包含字母t

  • 是否在结尾包含字母t

对应的代码及其结果如下:

str_replace_all("abstract", "t", "_")
## [1] "abs_rac_"
str_replace_all("abstract", "^t", "_")
## [1] "abstract"
str_replace_all("abstract", "t$", "_")
## [1] "abstrac_"

将所有文本字符开始或结束的位置替换成下划线_

str_replace_all("Are you OK", "\\b", "_")
## [1] "_Are_ _you_ _OK_"

通配符

通配符也属于匹配符,它包含两个层次:

  • 可以代替任意字符的特殊符号;

  • 可以代替特定类型内的任意字符的特殊符号。

通配符含义
.任意一个字符
\d十进制数字
\D\d的补码;十进制数字以外的任意一个字符
\s任意一个空白型字符,包括空格、Tab、换页符等
\w任意一个文本字符,包括字母、十进制数字、下划线_
\W\w的补码;任意一个非文本字符

str_replace_all("abstract", "t.a", "_")
## [1] "abs_ct"
str_replace_all("abstract", "t..a", "_")
## [1] "abstract"
  • abstract存在tra的部分,因此t.a模式可以被匹配;

  • abstract不存在ta间隔两个字母的部分,因此t..a模式不能被匹配;

x <- "abstract is necessary \n1. Introduction"

str_replace_all(x, "\\d", "_")
## [1] "abstract is necessary \n_. Introduction"
  • 使用带反斜杠的匹配符时需要在其前再加上一个反斜杠进行转义。

通配符也可以使用中括号[]进行自定义,表示括号内的任意一个字符。

str_replace_all("abstract", "t[r,s]a", "_")
## [1] "abs_ct"
  • [r,s]表示字母rs中的任意一个,因此只要tratsa中任意一个存在,t[r,s]a都能被匹配。

竖杠|表示前后整体的“或”,若为部分之间的“或”需要使用小括号:

str_replace_all("abstract", "tr|sa", "_")
## [1] "abs_ct"
str_replace_all("abstract", "t(r|s)a", "_")
## [1] "abs_ct"

系统中预定义的包含中括号的通配符及其含义:

通配符含义
|
[:digit:]数字
[:lower:]小写字母
[:upper:]大写字母
[:alnum:]大小写字母、数字
[:blank:]空格、制表符Tab
[:space:]空白型字符,范围比[:blank:]更大,包括换行符、换页符、回车符等
[:punct:]标点符号,包括如下:! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` {
[:graph:]大小写字母、数字、标点符号
[:print:]大小写母、数字、标点符号、空格
[:xdigit:]十六进制字符,包括如下:1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
[\u4e00-\u9fa5]汉字字符

# 是否包含数字
str_replace_all("abstract123", "[:digit:]", "_")
## [1] "abstract___"
# 是否包含大写字母
str_replace_all("abstractABC", "[:upper:]", "_")
## [1] "abstract___"
str_replace_all("摘要ABC", "[\u4e00-\u9fa5]", "_")
## [1] "__ABC"

限定符

上述例中曾使用两个点号..表示连续的两个任意字符。对此,限定符(Repetition)提供了更为简洁和灵活的表达方式。

限定符用来限制它前面的字符连续出现的次数。常见的限定符如下:

限定符数目限制
?至多出现一次,即0次或1次
*可以出现任意次,包括0次
+至少出现1次
{n}刚好出现n次
{n,}至少出现n次
{n,m}至少出现n次且至多出现m次

str_detect("abstract", "t..?a")
## [1] TRUE
str_detect("abstract", "t..*a")
## [1] TRUE
str_detect("abstract", "t..+a")
## [1] FALSE
str_detect("abstract", "t.{1}a")
## [1] TRUE

当限定符所限定的是多个字符的组合时,需要使用小括号:

str_detect("banana", "an{2}")
## [1] FALSE
str_detect("banana", "(an){2}")
## [1] TRUE

结语

本篇只是对正则表达式做了一个比较系统地介绍,并未包含所有的正则表达式。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值