4.5 字符串匹配
agrep 和 agrepl 函数做近似(模糊)匹配 (Approximate Matching or Fuzzy Matching) ,对于匹配,考虑到参数 pattern 在参数 x 中匹配时,允许参数值x存在最小可能的插入、删除和替换,这种修改叫做Levenshtein 编辑距离,max.distance 控制其细节
agrep(pattern, x, max.distance = 0.1, costs = NULL,
      ignore.case = FALSE, value = FALSE, fixed = TRUE,
      useBytes = FALSE)
agrepl(pattern, x, max.distance = 0.1, costs = NULL,
       ignore.case = FALSE, fixed = TRUE, useBytes = FALSE)agrep 函数返回 pattern 在 x 中匹配到的一个位置向量,agrepl 返回一个逻辑向量,这一点类似 grep 和 grepl 这对函数,下面举例子说明
agrep("lasy", "1 lazy 2")## [1] 1
# sub = 0 表示匹配时不考虑替换
agrep("lasy", c(" 1 lazy 2", "1 lasy 2"), max = list(sub = 0))## [1] 2
# 默认设置下,匹配时区分大小写
agrep("laysy", c("1 lazy", "1", "1 LAZY"), max = 2)## [1] 1
# 返回匹配到值,而不是位置下标,类似 grep(..., value = TRUE) 的返回值
agrep("laysy", c("1 lazy", "1", "1 LAZY"), max = 2, value = TRUE)## [1] "1 lazy"
# 不区分大小写
agrep("laysy", c("1 lazy", "1", "1 LAZY"), max = 2, ignore.case = TRUE)## [1] 1 3
startsWith(x, prefix)
  endsWith(x, suffix)startsWith 和 endsWith 函数用来匹配字符串的前缀和后缀,返回值是一个逻辑向量,参数 prefix 和 suffix 不要包含特殊的正则表达式字符,如点号.,举例子
# 字符串向量
search()## [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
## [4] "package:grDevices" "package:utils"     "package:datasets" 
## [7] "package:methods"   "Autoloads"         "package:base"
# 匹配以 package: 开头的字符串
startsWith(search(), "package:")## [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
# 或者
grepl("^package:", search())## [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
当前目录下,列出扩展名为 .Rmd 的文件
# list.files(path = ".", pattern = "\\.Rmd$")
# 而不是 endsWith(list.files(), "\\.Rmd")
endsWith(list.files(), ".Rmd")##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [13] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
## [25] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
## [37]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
## [49]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE
## [61] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE
## [73]  TRUE  TRUE
# 或者
grepl("\\.Rmd$", list.files())##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [13] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
## [25] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
## [37]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
## [49]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE
## [61] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE
## [73]  TRUE  TRUE
部分匹配(Partial String Matching)
match(x, table, nomatch = NA_integer_, incomparables = NULL)
x %in% table
charmatch(x, table, nomatch = NA_integer_)
pmatch(x, table, nomatch = NA_integer_, duplicates.ok = FALSE)这几个 match 函数的返回值都是一个向量,每个元素是参数x在参数table中第一次匹配到的位置,charmatch 与 pmatch(x, table, nomatch = NA_integer_, duplicates.ok = TRUE) 类似,所以 pmatch 在默认 duplicates.ok = FALSE 的情况下,若x在第二个参数table中有多次匹配就会返回 NA,因此,实际上 pmatch 只允许在第二个参数中匹配一次
match("xx", c("abc", "xx", "xxx", "xx"))## [1] 2
1:10 %in% c(1,3,5,9)##  [1]  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
# charmatch 就比较奇怪,规则太多
charmatch("", "")                             # returns 1## [1] 1
# 多个精确匹配到,或者多个部分匹配到,则返回 0
charmatch("m",   c("mean", "median", "mode", "quantile")) # returns 0## [1] 0
# med 只在table参数值的第二个位置部分匹配到,所以返回2
charmatch("med", c("mean", "median", "mode", "quantile")) # returns 2## [1] 2
charmatch("xx", "xx")## [1] 1
charmatch("xx", "xxa")## [1] 1
charmatch("xx", "axx")## [1] NA
# 注意比较与 charmatch 的不同
pmatch("", "")                             # returns NA## [1] NA
pmatch("m",   c("mean", "median", "mode")) # returns NA## [1] NA
pmatch("med", c("mean", "median", "mode")) # returns 2## [1] 2