【问题标题】:how to capture parenthesized groups with java regex如何使用 java regex 捕获带括号的组
【发布时间】:2011-05-19 18:46:58
【问题描述】:

我有一些类似的字符串:

(((a * b) + c) * d)

并希望使用 java 正则表达式捕获带括号的组。我认为这个简单的正则表达式

Pattern p = Pattern.compile("\\((.*)\\)",Pattern.DOTALL);

会做这项工作,但它不会。

这有什么问题?

【问题讨论】:

    标签: java regex


    【解决方案1】:

    不幸的是,您尝试使用正则表达式定义的语言闻起来很不规则,即正则表达式不适合这种类型的表达式。 (准确地说,“平衡括号”不是你可以用正则表达式定义的。)

    如果您只是想在示例中找到子字符串 a * b,则应该使用以下表达式:

    Pattern p = Pattern.compile("\\(([^()]*)\\)");
    Matcher m = p.matcher("(((a * b) * ) + c) * d)");
    if (m.find())
        System.out.println(m.group(1));   // prints "a * b"
    

    【讨论】:

    • +1 - 这绝对是非常规的。带有平衡括号的表达式的任何语法本质上都是递归的,但严格的 RE 会限制您进行交替和重复
    • 我不能 100% 确定 OP 是否正在尝试确定表达式是否具有平衡的括号。
    • 谢谢aioobe。我显然错过了“常规”的东西。当然,它是一个非正则表达式。我实际上想捕获所有组。这意味着我期望有 ((a * b) + c) * d (a * b) + c a * b
    • 好的。好吧,我只能说,你并不孤单。很多人在你之前遇到过这种情况:-)
    • @aioobe:你错了。用任何现代语言写a pattern for balanced parens 都是微不足道的。不幸的是,对于 OP,与许多其他与正则表达式相关的东西一样,Java 可笑的千禧年前眼罩使它完全不适合这些简单的任务。
    【解决方案2】:

    正则表达式不擅长提取括号等平衡对。你最好在没有正则表达式的情况下解析字符串。

    【讨论】:

    • 相反,他们是really quite good at it
    • @tchrist,您一直在隐瞒一个重要事实:您使用的“技巧”依赖于正则表达式的扩展,而这目前还不是通用标准。我真诚地建议您对这些 cmets 坚持使用 perl 和 php 标签。
    • @aioobe:我真诚地建议你停止假装 Java 以某种方式具有标准的正则表达式,将其他人贬低为仅仅是“技巧”。命名缓冲区几乎不是一个技巧。甚至支持这个千年的一个单一 Unicode 属性都不是什么技巧,包括 Unicode 脚本和非通用类别。支持逻辑代码点而不是 UTF-16 并不是一个技巧。支持字素集群不是诀窍。让"élève" 匹配\b\w+\b ANYWHERE 不是诀窍。不让"\t\n " 不正确地匹配^\s*\S+$ 不是诀窍。 一个技巧是处理Java的破碎!
    【解决方案3】:

    我相信使用 RegEx 处理嵌套结构几乎是不可能的。更好地遍历每个字符并跟踪您有多少个左括号。

    此外,如果您的目标是评估 infix notation 中的数学表达式,则使用 shunting algorithm 可能会更成功。

    【讨论】:

    • 我被告知,“虚拟”这个词总是被用作一种掩饰的委婉语——如果你愿意的话,就是狡猾的词——代表“不”。所以它就在这里,毕竟它实际上意味着not impossible
    猜你喜欢
    • 2011-01-18
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2020-03-15
    • 2017-12-30
    相关资源
    最近更新 更多