使用%in%运算符在R中进行部分字符串匹配吗?

时间:2019-06-18 13:12:13

标签: r regex string string-matching in-operator

我很想知道是否可以使用R中的%in%运算符进行部分字符串匹配。我知道有很多方法可以使用stringr等来查找部分字符串匹配,但是我当前的代码使用%in%运算符可以更轻松地工作。

例如,想象一下这个向量:

x <- c("Withdrawn", "withdrawn", "5-Withdrawn", "2-WITHDRAWN", "withdrawnn")

我希望每个都为TRUE,因为字符串包含“ Withdrawn”,但只有第一个为TRUE:

x %in% c("Withdrawn")
[1]  TRUE FALSE FALSE FALSE FALSE

我尝试使用正则表达式至少使其不区分大小写,但这使所有内容都不正确:

x %in% c("(?i)Withdrawn")
[1] FALSE FALSE FALSE FALSE FALSE

那么,是否可以使用带有包装程序的%in%运算符在所有这些代码上产生TRUE?因为使用tolower()或toupper()很容易,所以我不关心大小写敏感。但是,对我来说重要的是,代码将触发“撤回”,“撤回”和“ 5撤回”。

编辑:该问题被标记为该问题Case-insensitive search of a list in R的重复;但是,它有所不同,因为它询问是否可以使用%in%运算符来匹配部分字符串。链接的问题根本不使用%in%运算符。

1 个答案:

答案 0 :(得分:3)

%in%不支持此功能:它是match函数的包装器,该函数使用相等比较来建立匹配项,而不是正则表达式匹配项。但是,您可以实现自己的:

`%rin%` = function (pattern, list) {
     vapply(pattern, function (p) any(grepl(p, list)), logical(1L), USE.NAMES = FALSE)
}

这可以像%in%一样使用:

〉'^foo.*' %rin% c('foo', 'foobar')
[1] TRUE

请注意,结果与您按照grepl所期望的工作方式有所不同:模式匹配是不对称,因此您无法左右互换。如果只想将列表与单个正则表达式匹配,则直接使用grepl

〉grepl("(?i)Withdrawn", x)
[1] TRUE TRUE TRUE TRUE TRUE

或者,如果您更喜欢使用运算符:

`%matches%` = grepl
〉"(?i)Withdrawn" %matches% x
[1] TRUE TRUE TRUE TRUE TRUE