如何使用java正则表达式捕获带括号的组

如何使用java正则表达式捕获带括号的组,java,regex,Java,Regex,我有一些字符串,比如: (((a * b) + c) * d) 并希望使用java正则表达式捕获带括号的组。我以为这个简单的正则表达式 Pattern p = Pattern.compile("\\((.*)\\)",Pattern.DOTALL); 我会做这项工作,但它不会 这有什么问题?您试图用正则表达式定义的语言很不幸闻起来是非正则的,即正则表达式不适合这种类型的表达式。准确地说,平衡良好的括号不是可以用正则表达式定义的 但是,如果您只是想在示例中查找子字符串a*b,则应使用以下表达式

我有一些字符串,比如:

(((a * b) + c) * d)
并希望使用java正则表达式捕获带括号的组。我以为这个简单的正则表达式

Pattern p = Pattern.compile("\\((.*)\\)",Pattern.DOTALL);
我会做这项工作,但它不会


这有什么问题?

您试图用正则表达式定义的语言很不幸闻起来是非正则的,即正则表达式不适合这种类型的表达式。准确地说,平衡良好的括号不是可以用正则表达式定义的

但是,如果您只是想在示例中查找子字符串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可能会更成功-它肯定是非规则的。任何带有平衡括号的表达式的语法本质上都是递归的,但是严格的REs限制了你的交替和重复。我不能100%肯定OP是在试图弄清楚表达式是否有很好的平衡括号。谢谢大家。我显然错过了常规的事情。当然,它是一个非正则表达式。我其实想抓住所有的人。这意味着我希望有一个b+c*d a*b+c a*bOk。我只能说,你并不孤单。很多人在你之前都遇到过这样的情况:-@aioobe:你错了。用任何现代语言写作都是微不足道的。不幸的是,对于OP来说,这和其他许多与regex相关的事情一样,Java可笑的千禧年前的盲点使得它完全不适合于像这样的简单任务。我被告知,“虚拟”一词总是被用作一种掩饰性的委婉语——如果你愿意的话——表示“不”。这里就是这样,因为它毕竟实际上意味着。相反,它们是。@tchrist,你一直在掩盖一个重要事实:你使用的技巧依赖于正则表达式的扩展,而到目前为止,它还不是一个通用的标准。我真诚地建议您在这些评论中坚持使用perl和php标记。@aioobe:我真诚地建议您不要再假装Java有标准的正则表达式,而将其他人的正则表达式诋毁为纯粹的把戏。命名缓冲区绝非易事。在这个千年中,支持哪怕是一个Unicode属性都不是一个技巧,包括Unicode脚本和非常规类别。支持逻辑代码点而不是UTF-16不是一个技巧。支持grapheme集群不是什么把戏。让élève在任何地方匹配\b\w+\b都不是把戏。不让\t\n不正确地匹配^\s*\s+$不是诀窍。处理Java的脆弱性是一个技巧!