【问题标题】:Match "[abc]", "[[abc]", "[abc]]", but not "[[abc]]",匹配“[abc]”、“[[abc]”、“[abc]]”,但不匹配“[[abc]]”,
【发布时间】:2021-08-25 08:42:27
【问题描述】:

我正在尝试匹配[abc],除非它被[] 从双方“转义”(所以[[abc]] 被视为转义,但不是[[abc][abc]])。

我能找到的最接近的东西是来自Match "ABC" from *ABC*, but not from **ABC**(?<!\[)\[abc\](?!\]),但如果它只从一侧逃脱,它会忽略匹配。

【问题讨论】:

  • @WiktorStribiżew 我注意到您从这个问题中删除了c# 标签。 regex 标签的描述说“所有带有这个标签的问题还应该包括一个标签,指定适用的编程语言或工具”,所以你删除的 c# 标签并不是无关紧要的,因此我将它与 @ 一起添加回来987654332@,C# 使用的正则表达式引擎。例如,我的答案使用 .NET 提供的对可变长度后视的支持。
  • @WiktorStribiżew 这个问题有点复杂 + 这个问题有一个.net 特定的解决方案,可能不适合那个问题
  • 这里没有正则表达式是 .NET 特定的,现在可以在 Java、Python 甚至 JavaScript 中使用。

标签: c# .net regex escaping


【解决方案1】:

lookahead 可以在左侧或右侧,以允许在左侧或右侧有单个后备,但不能在另一侧使用双方括号。

(?<!\[)\[abc]|\[abc](?!])

Regex demo

【讨论】:

  • 嗨,很好的快速解决方案 (+1),但我认为您有兴趣了解我的另一种有助于避免模式重复的方法。非常感谢像您这样有经验的正则表达式用户的反馈。
【解决方案2】:

@Thefourthbird 的回答有效,但需要重复主要模式 abc,这与鼓励大多数人遵循的 DRY principle 背道而驰。

为了最大限度地重用代码,一种方法是使用捕获组来捕获[abc],然后以否定的后向模式使用它,以确保它前面不是[,后面是]:

(\[abc])(?<!\[\1(?=]))

Demo

请注意,这适用于 C#,因为 .NET 恰好支持可变长度的后视模式,而许多其他正则表达式引擎不支持这种模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多