51.关于模式匹配的一些函数(一)
【上一篇:50.关于正则表达式的基础知识】
【下一篇:52.关于模式匹配的一些函数(二)】
模式匹配和替换相关的函数包含以下几种功能:
1. 确定匹配模式的字符串
2. 找到匹配的位置
3. 提取匹配的内容
4. 用新值替换匹配项
5. 基于匹配拆分字符串
模式匹配示意图
Base R 中的模式匹配函数有:grep, grepl, regexpr, gregexpr, regexec and gregexec,模式替换函数有:sub、gsub。
1. 确定匹配模式的字符串
stringr包中的模式匹配函数的返回值类型一般分为三种:(输入是字向量)
1)返回与输入向量等长的逻辑向量,向量元素匹配到pattern为TRUE,反之为FALSE
2)返回正确匹配到pattern的向量元素的索引
3)返回正确匹配到pattern的向量元素的值
强调,此类函数的返回值都与string本身相关:string本身、string在向量中的索引和逻辑值。
在stringr包中,这三种形式的返回值分别通过三个函数实现:
# 返回逻辑值
str_detect(string, pattern, negate = FALSE)
# 返回正确匹配字符串的索引
str_which(string, pattern, negate = FALSE)
# 返回正确匹配字符串本身
str_subset(string, pattern, negate = FALSE)
string:输入字符向量
pattern:用字符串表示的正则表达式
negate:默认FALSE表示返回匹配上的结果,TRUE表示返回没有匹配上的结果
> fruit <- c("apple", "banana", "pear", "pinapple")
> str_detect(fruit,"apple")
[1] TRUE FALSE FALSE TRUE
> str_which(fruit,"apple")
[1] 1 4
> str_subset(fruit,"apple")
[1] "apple" "pinapple"
### 以下两种取字符串的方法实现的结果与str_subset一致
> fruit[str_detect(fruit,"apple")]
[1] "apple" "pinapple"
> fruit[str_which(fruit,"apple")]
[1] "apple" "pinapple"
### str_count函数是str_detect函数的变形,参数更简单
str_count(string, pattern = "")
其返回值是一个与输入向量等长的向量,向量的值为每个向量元素中匹配模式的个数
> str_count(fruit, "apple")
[1] 1 0 0 1
相对应的,base R中的函数及其Usage分别是:
# 返回逻辑值,记忆:grep + logical
grepl(pattern,x)
# 返回正确匹配到pattern的字符串的索引
grep(pattern,x,value=FALSE)
# 返回正确匹配到pattern的字符串的值
grep(pattern,x,value=TRUE)
记忆:关于两者的比较:
1) str_*类函数只有三个参数,功能比较单一; base R中的函数,参数很多。
grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE,
fixed = FALSE, useBytes = FALSE, invert = FALSE)
grepl(pattern, x, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
2) str_*的pattern参数默认用字符串表示的正则表达式,grep*中的pattern参数有多个选择:A)默认同str_*,此时fixed=FALSE;B)直接写正则表达式,但同时需要设置fixed=TRUE。
3) str_的negate参数的作用与grep的invert参数作用相同。str_*函数想实现grep*的B)功能,需要通过fixed函数。如下,四种形式等效。
# 函数的作用是返回match部分在string中的开始位置和结束位置
> test<-"AB$CD"
> str_locate(test,"\\$")
start end
[1,] 3 3
> str_locate(test,fixed("$"))
start end
[1,] 3 3
> regexpr("\\$",test,fixed=F)
[1] 3
attr(,"match.length")
[1] 1
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE
> regexpr("$",test,fixed=T)
[1] 3
attr(,"match.length")
[1] 1
attr(,"index.type")
[1] "chars"
attr(,"useBytes")
[1] TRUE
4) 记忆:str_*的string和pattern参数的顺序是string在前,pattern在后;grep*的正好相反
相关的应用和知识
1) R中取子集也无非是用逻辑值、索引、变量名,所以任何用到取子集的地方用这些函数都很方便。例如dplyr::filter中过滤。
2) str_count()函数的返回值是个数,因此可以用来统计string中某些字符的个数并返回。例如和dplyr::mutate结合使用生成新列,统计字符串中某些字符的个数。
3) 对于复杂的逻辑条件,比如说匹配a或b,且除非d否则not c,不要执着地用一个正则表达式写出来,善用一些逻辑运算符(或|
、与&
、非!
等,注意,不是||
、&&
),与str_detect函数结合会更简洁有效。下面举一个多个str_detect与逻辑运算符结合使用的例子:
> test<-c("ab","ef","ij","op","uv","bc","db")
> str_detect(test,"^a|b$")
[1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE
> str_detect(test,"^a") | str_detect(test,"b$")
[1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE
4) 在数字上下文中,逻辑向量中,FALSE认为是0,TRUE认为是1,因此可以用sum()和mean()函数计算正确匹配pattern的字符串的数量和所占比例。
> sum(str_detect(test,"^a|b$"))
[1] 2
> mean(str_detect(test,"^a|b$"))
[1] 0.2857143
5) 模式匹配中,match永远不会有overlap。
模式匹配永远不会有overlap