51.关于模式匹配的一些函数(一)

2021-09-03  本文已影响0人  心惊梦醒

【上一篇: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

【上一篇:50.关于正则表达式的基础知识】
【下一篇:52.关于模式匹配的一些函数(二)】

上一篇下一篇

猜你喜欢

热点阅读