如何执行负面环视搜索

How do I perform a negative lookaround search

我正在查找文本字符串中特定字符的所有实例,但以特定方式添加前缀和后缀的情况除外。

一个简单的例子是在字符串“I am a cat in a hat in a car”中找到“a”的所有实例,除了它出现在单词“cat”中的地方:

I am a cat in a hat in a car

组合否定后向断言和否定前瞻断言似乎不起作用,因为它会在其中一个断言被触发时失败,而不是仅在两个断言都被触发时失败。

使用正则表达式查找“​​a”但忽略“ca”会忽略单词“car”:

/(?<!c)a/g
I am a cat in a hat in a car

使用正则表达式查找“​​a”但忽略“at”会忽略单词“hat”:

/a(?!t)/g
I am a cat in a hat❌ in a car

将两者结合起来忽略“汽车”和“帽子”:

/(?<!c)a(?!t)/g
I am a cat in a hat❌ in a car

正则表达式似乎 NOR 这两个断言,是否可以对它们进行 NAND?

您可以嵌套环视,匹配 a 并断言左边不是 ca 后跟 t 并使用单词边界 \b 来防止部分单词匹配.

a(?<!\bca(?=t\b))

Regex demo

或者先用lookbehind写,断言不是c左边:

(?<!\bc(?=at\b))a

Regex demo

您可以使用异常标记 [^...] 并在两种正环视之间交替:/(?<=[^c])a|a(?=[^r])/g.

通过在一个或中设置两个例外,就像一个与非门和两个非门:

  1. 它们都必须为真才能匹配 1 和 1 => 0

  2. 只有一个异常需要为假,所以存在匹配项 0 和 1 => 1

  3. 如果两者都为假,那么也有一个匹配项 0 and 0 => 1

Segment Meaning
(?<=[^c])a Match literal "a" if there is anything BUT a literal "c" before it
| OR
a(?=[^r]) Match literal "a" if there is anything BUT a literal "r" after it

https://regex101.com/r/CWV0ff/1