如果后面没有字符串而是另一个字符串,则 R 中的模式匹配

Pattern matching in R if string NOT followed but another string

我正在尝试使用来自 stringr 包的 str_detect 在 R 中匹配以下内容。

我想检测给定的字符串后面或前面是否有 'and' 或“&”。例如,在:

string_1<-"A and B"
string_2<-"A B"
string_3<-"B and A"
string_4<-"A B and C"

我希望 str_detect(string_X) 对于 string_1、string_3 和 string_4 为假,但对于 string_2 为真。

我试过:


str_detect(string_X,paste0(".*(?<!and |& )","A"))==TRUE & str_detect(string_X,paste0(".*","A","(?! and| &).*"))==TRUE)


我使用 paste0 是因为我想 运行 在不同的字符串上使用它。这适用于上述所有情况,除了 4。我是正则表达式的新手,而且它看起来也不是很优雅。有更通用的解决方案吗?

谢谢。

首先让我们将四个字符串组合成一个向量:

strings <- c(string_1, string_2, string_3, string_4)

正在使用

library(stringr)

str_detect(strings, "(A|B)(?=\s(and|&))", negate = TRUE)

我们寻找“A”或“B”后跟“and”或“&”。所以这个returns

#> [1] FALSE  TRUE FALSE FALSE

你可以把它包装成一个函数:

detector <- function(letters, strings) {
  pattern <- paste0("(", paste0(letters, collapse = "|"), ")(?=\s(and|&))")
  str_detect(strings, pattern, negate = TRUE)
}

detector(c("A", "B"), strings)
#> [1] FALSE  TRUE FALSE FALSE

detector(c("A"), strings)
#> [1] FALSE  TRUE  TRUE  TRUE

detector(c("B"), strings)
#> [1]  TRUE  TRUE FALSE FALSE

detector(c("C"), strings)
#> [1] TRUE TRUE TRUE TRUE

您可以使用积极的先行断言来确保不存在 AB 后跟 and& 并且也不存在其他订单。

^(?!.*[AB] (?:and|&))(?!.*(?:and|&) [AB])
  • ^ 字符串开头
  • (?!.*[AB] (?:and|&)) 断言字符串不包含 AB 后跟 and or &
  • (?!.*(?:and|&) [AB]) 断言字符串不包含 and 或 & 后跟 A 或 B

Regex demo | R demo

library(stringr)

string_1<-"A and B"
string_2<-"A B"
string_3<-"B and A"
string_4<-"A B and C"
string_5<-"& B"

strings <- c(string_1, string_2, string_3, string_4, string_5)

str_detect(strings, "^(?!.*[AB] (?:and|&))(?!.*(?:and|&) [AB])")

输出

[1] FALSE  TRUE FALSE FALSE FALSE