用正则表达式匹配前面没有另一个字符串
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
前面没有 A
的 B
。
请注意,此 ([^A])B
正则表达式匹配第一个 XB
并捕获 X
。因为 X
后面的 B
已经出现在匹配中,所以不会再次匹配。在这种情况下,我建议您使用环视。
([^A])(?=B)
(?=B)
肯定前瞻断言匹配后必须跟字母 B
.
但是当替换字符串为 AB
时它会生成 XABBABB
。要获得所需的输出,只需从替换字符串中删除 B
。即用 A
替换匹配的字符
所有 B 前面不带 AB 的 A。
查找:(?<!A)B
替换:AB
在 .NET 正则表达式风格中,您可以像这样使用 lookbehinds:
匹配foo
而不是立即前面有bar
(?<!bar)foo
参见regex demo。
匹配 foo
前面没有 bar
字符串中的任何地方
(?s)(?<!bar.*?)foo
参见regex demo。
立即匹配foo
bar
(?<=bar)foo
参见regex demo。
匹配 foo
前面有 bar
字符串中的任意位置
(?s)(?<=bar.*?)foo
参见regex demo。
后者在负后视中包含 .*?
,允许正则表达式引擎检查 bar
以及紧邻 foo
左侧的任何零个或多个字符,因此 bar
不必紧接在 foo
.
之前
(?s)
内联修饰符允许 .
匹配任何字符,包括换行符。
当前的问题很容易通过使用负向后看来解决(见上面的场景),
var result = Regex.Replace("XBB", "(?<!A)B", "AB");
声明
Regex.Replace("XB", "([^A])B", "AB")
产生 XAB
,正如预期的那样。谁能解释一下为什么
Regex.Replace("XBB", "([^A])B", "AB")
不是产生XABAB
,而是XABB
吗?这就像正则表达式解析器在到达第二个 B 时不再知道前面的字符。
最终,我想用 AB
替换所有 B
前面没有 A
的 B
。
请注意,此 ([^A])B
正则表达式匹配第一个 XB
并捕获 X
。因为 X
后面的 B
已经出现在匹配中,所以不会再次匹配。在这种情况下,我建议您使用环视。
([^A])(?=B)
(?=B)
肯定前瞻断言匹配后必须跟字母 B
.
但是当替换字符串为 AB
时它会生成 XABBABB
。要获得所需的输出,只需从替换字符串中删除 B
。即用 A
所有 B 前面不带 AB 的 A。
查找:(?<!A)B
替换:AB
在 .NET 正则表达式风格中,您可以像这样使用 lookbehinds:
匹配foo
而不是立即前面有bar
(?<!bar)foo
参见regex demo。
匹配 foo
前面没有 bar
字符串中的任何地方
(?s)(?<!bar.*?)foo
参见regex demo。
立即匹配foo
bar
(?<=bar)foo
参见regex demo。
匹配 foo
前面有 bar
字符串中的任意位置
(?s)(?<=bar.*?)foo
参见regex demo。
后者在负后视中包含 .*?
,允许正则表达式引擎检查 bar
以及紧邻 foo
左侧的任何零个或多个字符,因此 bar
不必紧接在 foo
.
(?s)
内联修饰符允许 .
匹配任何字符,包括换行符。
当前的问题很容易通过使用负向后看来解决(见上面的场景),
var result = Regex.Replace("XBB", "(?<!A)B", "AB");