【问题标题】:How can I recursively match a pattern using Regular Expressions?如何使用正则表达式递归匹配模式?
【发布时间】:2011-12-28 18:30:24
【问题描述】:

字符串可以是以下之一:

a(b,c)
a(a(b,c),d)
a(a(a(a(a(b,c),d),a(e,f)),g),h)
etc

我想匹配无限数量的“a(x,y)”。我如何使用正则表达式来做到这一点?这是我所拥有的:

\\w\\(((?:\\([a-zA-Z0-9]+\\))|(?:[a-zA-Z0-9]+)),((?:\\([a-zA-Z0-9]+\\))|(?:[a-zA-Z0-9]+))\\)

它只匹配“a(x,y)”的两个递归。

【问题讨论】:

标签: java regex


【解决方案1】:

Java 的标准正则表达式库不支持递归,因此无法匹配这种通用的嵌套结构。

但在支持递归的风格(Perl、PCRE、.NET 等)中,您可以使用如下表达式:

\w+(?:\((?R)(?:,(?R))*\))?

【讨论】:

  • 你确定Python有这样的功能吗? AFAIK,只有 PHP、.NET 和 Perl 能够做到这一点。
  • @BartKiers,正确,Python 没有(?R) 和朋友,出于某种原因,我认为其正则表达式引擎的较新版本确实支持它。已将其从列表中删除。
  • 我对 Python 不太熟悉,所以我认为他们将它包含在 v3 中(我还没有真正看过)。
  • 也许你想到了 Ruby。从 1.9 版开始,它使用了支持递归的 Oniguruma 正则表达式库。
  • @AlanMoore,Oniguruma 是我想的那个,谢谢你提醒我。
【解决方案2】:

你也可以使用我的正则表达式库https://github.com/florianingerl/com.florianingerl.util.regex,它支持递归正则表达式! API与java.util.regex的API基本相同,只是需要的import语句不同,例如

Pattern p = Pattern.compile("(?<first>a\\((?<second>(?'first')|[a-zA-Z]),(?'second')\\))");
assert p.matcher("a(a(a(a(a(b,c),d),a(e,f)),g),h)").find();

【讨论】:

  • 不支持吗?R
【解决方案3】:

2 个选项 - 1) 使用词法分析自行进行模式匹配和替换 [OR] 2) 如果您想坚持使用 Regex,请使用一些 shell 编程(或任何支持语言)并从 Java 中调用它。

【讨论】:

    【解决方案4】:

    您描述的语言不是regular language,因此无法通过正则表达式匹配。查看lexical analysis(即使用解析器)

    【讨论】:

    • -1。正则表达式(在这种情况下)不是常规的,而且它们已经有 25 年多了。
    • Nitpick:词法分析基于正则表达式;词法分析根据正则表达式定义的规则将字符流转换为符号流。解决提问者所问问题的是解析器生成器。
    • @robert,(显然?)Qtax 表示操作系统工具/编程 API 中的正则表达式。在这种情况下,正则表达式能够匹配之前匹配的内容(分组和反向引用):使它们能够匹配比常规语言更多的内容。
    • 重点是,简单地说“这不是常规语言”是没有帮助的。我们谈论的是regexes,而不是纯理论的正则表达式。一些正则表达式支持递归,但 Java 并不是其中之一。
    【解决方案5】:

    我认为您正在寻找类似的东西:

    a(x,y) = [a-z] ( [a-z] , [a-z] )

    正则表达式 = a(x,y) | a(正则表达式|y) | a(x, 正则表达式)

    不知道你怎么能用一种语言做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2019-10-30
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多