如何在Java中匹配括号内的字符串(嵌套)?

如何在Java中匹配括号内的字符串(嵌套)?,java,regex,nested,Java,Regex,Nested,我想匹配括号内的字符串,如: (i, j, k(1)) ^^^^^^^^^^^^ 字符串也可以包含闭括号。如何在不编写解析器的情况下将其与Java中的正则表达式匹配,因为这是我项目的一小部分。谢谢 编辑: 我想搜索一个字符串块,为我的Fortran翻译应用程序找到类似u(I,j,k),u(I,j,k(1))或只是u(),并将它们替换为\u%array(I,j,k)和\u%array(I,j,k(1))。让正则表达式: ([a-z]+)\((.*)\) 第一组包含标识符,第二组包含参数。然后进

我想匹配括号内的字符串,如:

(i, j, k(1))
^^^^^^^^^^^^
字符串也可以包含闭括号。如何在不编写解析器的情况下将其与Java中的正则表达式匹配,因为这是我项目的一小部分。谢谢

编辑:


我想搜索一个字符串块,为我的Fortran翻译应用程序找到类似
u(I,j,k)
u(I,j,k(1))
或只是
u()
,并将它们替换为
\u%array(I,j,k)
\u%array(I,j,k(1))
。让正则表达式:

([a-z]+)\((.*)\)
第一组包含标识符,第二组包含参数。然后进行如下处理:

private static final Pattern PATTERN = Pattern.compile("([a-z]+)\\((.*)\\)");

// ...

final Matcher m = Pattern.matcher(input);

if (!m.matches())
    // No match! Deal with it.

// If match, then:

final String identifier = m.group(1);
final String params = m.group(2);

// Test if there is a paren
params.indexOf('(') != -1;

用Fortran中的标识符替换
[a-z]+

请检查此答案,因为它基本上完成了您尝试执行的操作(简而言之,使用regexps不太可能)


正如我所说,与流行的观点相反(不要相信人们所说的一切),匹配嵌套括号在正则表达式中是可能的

使用它的缺点是,您只能进行固定级别的嵌套。对于你希望支持的每一个附加级别,你的正则表达式都会越来越大

但不要相信我的话。让我给你看看。正则表达式:

\([^()]*\)
。对于,您需要:

\(([^()]*|\([^()]*\))*\)
等等。要继续添加级别,只需将中间(第二)部分更改为
([^()]*.
部分([^()]*.\([^()]*\)*.)。就像我说的,它会越来越大

您的问题: 对于您的情况,两个级别可能就足够了。因此,它的Java代码是:

String fortranCode = "code code u(i, j, k) code code code code u(i, j, k(1)) code code code u(i, j, k(m(2))) should match this last 'u', but it doesnt.";
String regex = "(\\w+)(\\(([^()]*|\\([^()]*\\))*\\))"; // (\w+)(\(([^()]*|\([^()]*\))*\))
System.out.println(fortranCode.replaceAll(regex, "__$1%array$2"));
输入:

code code u(i, j, k) code code code code u(i, j, k(1)) code code code u(i, j, k(m(2))) should match this last 'u', but it doesnt.
输出:

code code __u%array(i, j, k) code code code code __u%array(i, j, k(1)) code code code u(i, j, __k%array(m(2))) should match this last 'u', but it doesnt.
底线: 在一般情况下,解析器将做得更好-这就是为什么人们对它如此恼火的原因。但是对于简单的应用程序,正则表达式就足够了


注意:一些风格的正则表达式支持嵌套操作符
R
(Java不支持,PCRE引擎如PHP和Perl-do),这允许嵌套任意数量的级别。有了它们,你可以做:
\([^()]|(?R))*\)

是否有最大的“深度”妄想,或者你可以有任何深度?听起来你不需要一个非常复杂的解析器……你不能用正则表达式做这件事,至少不能用Java,因为正则表达式不是递归的。不过,PCRE可以做到这一点。但是您应该使用/编写解析器。例如,你可以试试。@radai我没有深度限制,但如果需要,我可以接受。@LiDong这可能是一个错误。你到底想要什么?告诉我字符串的格式是否正确?里面的数据是什么?什么?没错,正则表达式(至少在Java中)不是执行此任务的合适工具。我想我应该改变我的计划,只匹配
u(
,并将其替换为
\uu%array(
@acdjunior先生,您能解释一下为什么这个正则表达式:
\((?:[^()]\124;(?:\([^()]*\)*\)
对任何深度都不起作用?@AhmedAkhtar,因为它只匹配两个级别。粗略地说,它只匹配两个级别,因为在第二个括号打开后,它“忽略”任何其他括号打开,这意味着它找到的第一个关闭括号,它认为它正在关闭第二个打开的(而不是最后一个打开的)。例如:
aaa 1(aaa 2(aaa 3(aaa 4)aaa 5)aaa 6)aaa..
,在这种情况下,两级正则表达式将
4)
解释为关闭
2(
,而不是
3(
如您所料。先生,请尝试回答之前的评论,我发表此评论已经快一年了,我真的不记得我问这个问题的背景。无论如何,谢谢。@AhmedAkhtar是的,当然,对延迟表示歉意。有时我们不立即回答,最终完全忘记了。请尝试无论如何,下次要快一点。干杯!我认为这个正则表达式不适用于(abc(de)(fg)hi之类的嵌套模式。可以对正则表达式做什么修改来支持这一点?