【发布时间】:2019-10-07 02:56:48
【问题描述】:
我正在尝试将大量单词与一列字符串进行匹配。这些词必须完全匹配。
我可以一次只用一个词,但对于多个词我会遇到一些问题。
x = c("red", "redish", "green", "greenish")
grepl("red|green", ignore.case=TRUE, x)
我希望它返回“红色”和“绿色”;但不会偏红或偏绿。
【问题讨论】:
我正在尝试将大量单词与一列字符串进行匹配。这些词必须完全匹配。
我可以一次只用一个词,但对于多个词我会遇到一些问题。
x = c("red", "redish", "green", "greenish")
grepl("red|green", ignore.case=TRUE, x)
我希望它返回“红色”和“绿色”;但不会偏红或偏绿。
【问题讨论】:
正则表达式让您使用\\b 来表示单词边界:
grepl("\\bred\\b|\\bgreen\\b", x, ignore.case = TRUE)
# [1] TRUE FALSE TRUE FALSE
如果您想匹配较长字符串中的单词,这将很有效:
grepl("\\bred\\b|\\bgreen\\b",
c("I want to match red", "But not Fred",
"Green yes please", "ignore wintergreen"),
ignore.case=TRUE)
# [1] TRUE FALSE TRUE FALSE
但是,如果你在做整个字符串匹配,正则表达式是多余的,相等匹配会快得多:
tolower(x) %in% c("red", "green")
[1] TRUE FALSE TRUE FALSE
如果我们从patterns = c("red|green") 开始,我们可以得到上述任何一种情况:
## use this with `%in%`
individual_words = unlist(strsplit(patterns, split = "\\|"))
## or paste on the word boundaries for regex
word_boundary_patterns = paste0("\\b", individual_words, "\\b", collapse = "|")
【讨论】:
(?<!-)\\byear-old\\b,其中(?<!-) 表示“前面没有破折号”。您可以see here 如何定义单词边界。像这样的特殊情况将不得不特殊处理。
您还可以使用^ 和$ 分别指定字符串的开头和结尾:
grepl("^red$|^green$", ignore.case = T, x)
【讨论】: