15

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

(i, j, k(1))
^^^^^^^^^^^^

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

编辑:

我想搜索一个字符串块并找到类似的东西u(i, j, k)u(i, j, k(1))或者只是u(<anything within this paired parens>),并将它们替换__u%array(i, j, k)__u%array(i, j, k(1))我的 Fortran 翻译应用程序。

4

3 回答 3

26

正如我所说,与流行的看法相反(不要相信人们所说的一切),使用正则表达式匹配嵌套括号可能的。

使用它的缺点是您只能达到固定级别的嵌套。对于您希望支持的每一个额外级别,您的正则表达式将越来越大。

但不要相信我的话。我来给你展示。正则表达式:

\([^()]*\)

匹配一级。对于最多两个级别,您需要:

\(([^()]*|\([^()]*\))*\)

等等。要继续添加级别,您只需将中间(第二)[^()]*部分更改为([^()]*|\([^()]*\))*在此处检查三个级别)。正如我所说,它会变得越来越大。

你的问题:

对于您的情况,两个级别可能就足够了。所以它的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 不支持,PHP 和 Perl 等 PCRE 引擎支持),它允许您嵌套任意数量的级别。有了它们,您可以\(([^()]|(?R))*\)

于 2013-07-20T06:08:22.200 回答
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;

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

于 2013-07-20T05:44:13.713 回答
0

请检查此答案,因为它基本上可以完成您尝试做的事情(简而言之,使用正则表达式实际上是不可能的)

正则表达式匹配外括号

于 2013-07-20T05:54:04.573 回答