如何在正则表达式中处理多个括号?

时间:2010-05-03 17:06:17

标签: java regex

我有这种类型的字符串:

文字(更多文字)

我想要做的是使用正则表达式来提取字符串的“更多文本”段。到目前为止,我一直在使用这个正则表达式:

"^.*\\((.*)\\)$"

虽然它适用于很多情况,但如果我有类似的东西似乎会失败:

文字(更多文字(更多文字))

我得到的是:更多文字)

我想要的是:  更多文本(甚至更多文本)(基本上是最外面一对括号的内容。)

7 个答案:

答案 0 :(得分:4)

除了懒惰量化之外,另一种方式是:

"^[^(]*\\((.*)\\)$"

在两个正则表达式中,在匹配组之前有一个显式指定的左括号("\\(",带有Java String转义)。在原文中,之前有一个.*,允许任何内容(包括其他左括号)。在我的情况下,这里不允许使用左括号(有一个negated character class),所以在最外层显式指定了左括号。

答案 1 :(得分:3)

尝试:

"^.*?\\((.*)\\)$"

这应该使第一次匹配不那么贪心。贪婪意味着它可以吞下一切可能的东西,同时仍然可以获得整体模式匹配。

另一个建议:

"^[^(]*\\((.*)\\)$"

可能会更符合你所寻找的方面。对于这个简单的例子,它并不重要,但如果你想扩展正则表达式,例如通过使大括号内的部分可选,那就可以了。

答案 2 :(得分:3)

我推荐这个(删除反斜杠的双重转义,因为这不是正则表达式的一部分):

^[^(]*\((.*)\)

与您的版本(^.*\((.*)\)$)匹配如下:

  1. 明星贪婪地匹配,所以你的第一个.*就到了字符串的末尾。
  2. 然后它根据需要回溯,因此\(可以匹配 - 这将是字符串中的最后一个开头。
  3. 然后下一个.*再次到达字符串的末尾。
  4. 然后它同样回溯,以便\)可以匹配,即到最后一个结束时。
  5. 当您使用[^(]*而不是.*时,它不能超过第一个开启页面,因此字符串中的第一个打开paren(正确一个)将划分你的子赛事。

答案 3 :(得分:1)

试试这个:

"^.*?\\((.*)\\)$"

答案 4 :(得分:1)

真正的正则表达式不能计算括号;这需要一个下推自动机。一些正则表达式库有扩展来支持这一点,但我认为Java没有(可能是错的; Java不是我的强项)。

顺便说一句,到目前为止我看到的其他答案将与给出的例子一起使用,但会打破,例如,text (more text (even more text)) (another bit of text)。改变贪婪并不能弥补无法计算。

答案 5 :(得分:0)

$str =~ /^.*?\((.*)\)/

答案 6 :(得分:-1)

我认为原因是因为你的第二张通配符正在拾取右括号。你需要排除它。