如何在正则表达式中包含多个具有逻辑运算符的负前瞻和后视条件



我需要将所有出现"dog"的字符串转换为"cat",除非字符串是"棕色狗跳起来"或"狗大声吠叫",在这种情况下它们应该保持不变。

我尝试使用负前瞻和后视。

这是我的例子。

str = c("brown dog", "brown dog jumps up", "dog jumps up", "dog barks loudly", "dog ran out")

预期结果为:

CAT, brown dog jumps up, CAT, dog barks loudly, CAT

我尝试了第一个条件,但它似乎在非此即彼的基础上工作,即要么前面没有"棕色",要么后面没有"跳起来"。正则表达式是否不按三个条件(棕色/狗/跳起来(的顺序工作?

gsub('.*(?<!brown )dog(?! jumps up).*', "CAT", str, perl = TRUE)

以下正则表达式有效,但是如果我使用"OR",为什么"棕色狗"和"狗跳起来"保持不变?

gsub('.*(?<!brown )dog.*|.*dog(?! jumps up).*', "CAT", str, perl = TRUE)

在上述基础上,我添加了第三种模式,但这会将所有内容更改为"CAT"。

gsub('.*(?<!brown )dog.*|.*dog(?! jumps up).*|.*dog(?! barks loudly).*', "CAT", str, perl = TRUE)

为什么|在此代码中充当 AND?如何将除"棕色狗跳起来"和"狗大声吠叫"之外的所有内容更改为"CAT"?

为什么不只检查"dog"的出现和没有strings的出现并将它们更改为"CAT"

strings <- c('dog barks loudly', 'brown dog jumps up')
str[grepl('dog', str) & (!str %in% strings)] <- "CAT"
str
#[1] "CAT"  "brown dog jumps up" "CAT"  "dog barks loudly"   "CAT" 

如果您正在寻找strings模式而不是完全匹配,我们可以做

strings <- paste0(c('dog barks loudly', 'brown dog jumps up'), collapse = "|")
str[grepl('dog', str) & !grepl(strings, str)] <- "CAT"

我们可以在单个grep中执行此操作,并使用invert = TRUE

str[grep("(brown dog jumps up)|(dog barks loudly)", str, invert = TRUE)] <- "CAT"
str
#[1] "CAT"  "brown dog jumps up" "CAT"  "dog barks loudly"   "CAT" 

最新更新