用正则表达式匹配前面没有另一个字符串

Match string not preceded by another with a regular expression

声明

Regex.Replace("XB", "([^A])B", "AB")

产生 XAB,正如预期的那样。谁能解释一下为什么

Regex.Replace("XBB", "([^A])B", "AB")

不是产生XABAB,而是XABB吗?这就像正则表达式解析器在到达第二个 B 时不再知道前面的字符。

最终,我想用 AB 替换所有 B 前面没有 AB

请注意,此 ([^A])B 正则表达式匹配第一个 XB 并捕获 X 。因为 X 后面的 B 已经出现在匹配中,所以不会再次匹配。在这种情况下,我建议您使用环视。

([^A])(?=B)

(?=B) 肯定前瞻断言匹配后必须跟字母 B.

但是当替换字符串为 AB 时它会生成 XABBABB。要获得所需的输出,只需从替换字符串中删除 B。即用 A

替换匹配的字符

DEMO

所有 B 前面不带 AB 的 A。

查找:(?<!A)B
替换:AB

在 .NET 正则表达式风格中,您可以像这样使用 lookbehinds:

匹配foo而不是立即前面有bar

(?<!bar)foo

参见regex demo

匹配 foo 前面没有 bar 字符串中的任何地方

(?s)(?<!bar.*?)foo

参见regex demo

立即匹配foobar

(?<=bar)foo

参见regex demo

匹配 foo 前面有 bar 字符串中的任意位置

(?s)(?<=bar.*?)foo

参见regex demo

后者在负后视中包含 .*?,允许正则表达式引擎检查 bar 以及紧邻 foo 左侧的任何零个或多个字符,因此 bar 不必紧接在 foo.

之前

(?s) 内联修饰符允许 . 匹配任何字符,包括换行符。

当前的问题很容易通过使用负向后看来解决(见上面的场景),

var result = Regex.Replace("XBB", "(?<!A)B", "AB");