【问题标题】:How to ignore positive/negative lookbehind/lookahead groups in a regex? [duplicate]如何忽略正则表达式中的正/负后瞻/前瞻组? [复制]
【发布时间】:2020-10-02 14:42:57
【问题描述】:

是否有一种简单的方法可以使用另一个正则表达式从正则表达式中删除正/负后向/前瞻组(考虑括号内)?

示例源表达式:A(?<!B(C)D)E(?<=F)G(?!H(I(J))K)L(?=M(O)P)Q(?>R)S(T) 我要删除的部分:

  • (?<!B(C)D)
  • (?<=F)
  • (?!H(I(J))K)
  • (?=M(O)P)

到目前为止,我使用表达式\(\?\<?[!=].+?\) 来查找要删除的部分,但内括号会产生问题...例如,不是查找(?<!B(C)D) 部分,而是查找(?<!B(C)...

我考虑过用(?# 替换(?<!(?!(?<=(?=(将它们转换为嵌入式评论),这在“regex101.com”上非常有效,但遗憾的是在 JAVA 中不行。 ..

我试图避免用一堆 if-else 逻辑遍历每个字符。

注意:我在 Java (Kotlin) 中使用这些正则表达式,并使用“containsMatchIn”方法将源表达式与实际文本匹配。

【问题讨论】:

  • 我会编写或使用解析器——当您可以拥有任意嵌套的括号时,拥有一个堆栈会很有帮助,因为正则表达式无法存储状态。如果您确实使用正则表达式,则需要一个递归表达式。这比欺骗目标建议的要难一些,因为您需要省略转义的子字符串,例如 \( 和其他边缘情况,但它应该为您提供一个起点。
  • @ggorlen Recusion 似乎很有前途,直到我发现它在 Java 中不可用。 :-(

标签: java regex


【解决方案1】:

您必须使用与 PERL 兼容的正则表达式,而不是标准的 Java 正则表达式,因为它们不支持递归。试试这个:\(\?<?[!=](?<r>[^()]|\(\g<r>+\))+\)

  • \(\?<?[!=]\) 是断言的开始和结束,
  • (?<r>[^()]|\(\g<r>+\))+ 是带有平衡括号的字符串的正则表达式,
  • [^()]|\(\g<r>+\) 要么是非括号,要么是括号内带有平衡括号(递归调用)的字符串,
  • \g<r> 是对上一条规则的递归调用。

已保存:https://regex101.com/r/mjMoyz/1

【讨论】:

【解决方案2】:

我终于找到了解决方案...不得不做一些开箱即用的思考:-)

下面的代码起到了作用,基本上表现得像 PERL 的注释组构造 (?#...)

使用字符串替换:

表达式 = 表达式.replace("(?").replace("(?").replace("(?=", "(?=|")

或使用正则表达式替换:

表达式 = 正则表达式("""((?!)""").replace(Regex("""((?=)""").replace(表达式, "$1|"), "$1_")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多