在 R 中使用 AND 和 OR 布尔运算符检测字符串

zes*_*sla 4 regex r stringr

我有这样的文字:

text = 'I love apple, pear, grape and peach'
Run Code Online (Sandbox Code Playgroud)

如果我想知道文本是否包含applepear。我可以执行以下操作并且工作正常:

str_detect(text,"apple|pear")
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我想像这样使用布尔值怎么办(apple OR pear) AND (grape)。无论如何我可以把它放进去str_detect()。那可能吗?以下是工作:

str_detect(text,"(apple|pear) & (grape)" )
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

我想知道这一点的原因是我想编程以将“布尔查询”转换为grepor str_detect。就像是:

str_detect(text, '(word1|word2) AND (word2|word3|word4) AND (word5|word6) AND .....')
Run Code Online (Sandbox Code Playgroud)

数量AND不一....

请没有多个解决方案str_detect

Ice*_*can 6

您可以将所有模式作为向量传递给 str_detect 并检查它们是否都TRUE带有all.

patterns <- c('apple|pear', 'grape')
all(str_detect(text, patterns))
Run Code Online (Sandbox Code Playgroud)

或与基地 R

all(sapply(patterns, grepl, x = text))
Run Code Online (Sandbox Code Playgroud)

或者,您可以将模式放在列表中并使用映射,这将为 OR(或您可能想要作为列表元素放置的任何其他内容)提供更详细的输出

patterns <- list(c('apple', 'pear'), 'peach')
patterns %>% 
  map(str_detect, string = text)

# [[1]]
# [1] TRUE TRUE
# 
# [[2]]
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

也可以将其写为单个正则表达式,但我认为没有理由这样做

patterns <- c('apple|pear', 'grape')
patt_combined <- paste(paste0('(?=.*', patterns, ')'), collapse = '')
str_detect(text, patt_combined)
Run Code Online (Sandbox Code Playgroud)

patt_combined

# [1] "(?=.*apple|pear)(?=.*grape)"
Run Code Online (Sandbox Code Playgroud)