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)
%in% table
x 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