【问题标题】:Match string not preceded by another with a regular expression用正则表达式匹配前面没有另一个字符串的字符串
【发布时间】:2015-01-12 17:52:53
【问题描述】:

声明

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

按预期生成XAB。谁能解释一下原因

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

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

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

【问题讨论】:

  • 您选择的答案不会真正起作用。为了将来参考,我会等待一段时间的替代答案。

标签: .net regex


【解决方案1】:

所有 B 前面都没有 A 和 AB。

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

【讨论】:

  • 确实看起来不错。这比我接受的答案更简单、更合乎逻辑。您能否提供一个示例,说明@Avinash 的解决方案在您的解决方案有效时却失败了?
  • @FrançoisBeaune:这个答案和另一个答案有一个区别:这个答案将替换字符串开头的B,而另一个答案不会。不过,您不太清楚在这种情况下会发生什么。
  • 确实,我必须使用([^A]|^)(?=B) 才能使它在字符串的开头也起作用。您的解决方案更简单、更干净。
  • 此答案中的模式对于将带有 Unix 换行符的文本转换为带有 DOS/Windows 换行符的文本很方便,调整如下:(?<!\r)\n
  • 请注意,即使是现在 2021 年的 safari 仍然不支持后视功能。
【解决方案2】:

在 .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

后者包含.*? 在否定的lookbehind 允许正则表达式引擎检查bar 和紧靠foo 左侧的任何零个或多个字符,因此bar 不必紧跟在前面foo.

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

当前的问题很容易通过使用否定的lookbehind解决(见上面的场景),

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

【讨论】:

  • 我知道最初的答案是关于 .NET,但是有没有什么方法可以在没有 "lookbehind assertion is not fixed length" 错误的情况下使用 PCRE 实现 (?&lt;!bar.*?)foo 行为?
  • @IvanShatsky 是的,使用bar.*foo(*SKIP)(*F)|foo 甚至bar.*?foo.*(*SKIP)(*F)|foo
  • 哇,非常感谢,以前不知道(*SKIP)(*F)。如果有人像我一样第一次遇到(*SKIP)(*F),你可以找到解释here
  • 这适用于 JS(regexr.com/652sd) 但不适用于 powershell。我正在使用-replace 替换字符。 -replace '(?&lt;!")(n)', ''。我正在尝试删除除" 之外的任何字符之后出现的新行。我的命令出了什么问题。
  • @hirani89 (Get-Content $filepath -Raw) -replace '(?m)(?&lt;=[^\r\n"])(?:\r\n?|\n)'
【解决方案3】:

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

([^A])(?=B)

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

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

DEMO

【讨论】:

  • 我编辑了我的问题以阐明我的目标。我想得到XABAB。有了你的建议,我得到XABBABB
猜你喜欢
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多