0
{{ info {{ abc}} {{ last}} }} {{ fast}}

在这个字符串中,我只需要提取数据,使开始和结束括号平衡。即在这种情况下我需要

  1. {{ info {{ abc}} {{ last}} }}
  2. {{ fast}}

我目前使用的正则表达式是

(\\ {\\{.*\\}\\}) *

但它给了我整个字符串,而不是我期望的字符串。如何正确地做到这一点?

String line="{{ Infobox {{aks}} {{ska}}  }} akshat {{ las}}";
String pattern;
System.out.println(line);
Pattern r=Pattern.compile("(\\{\\{.*\\}\\})*");
Matcher m=r.matcher(line);

输出是整个字符串...不是我期望的

4

2 回答 2

4

使用 Java 正则表达式无法解决此问题。

正则表达式(在数学意义上)无法根据递归语法解析输入。并且您需要递归语法来描述一种语言(例如这种语言),其中任意嵌套的括号是平衡的。

虽然 Java 正则表达式比数学表达式更强大,但它们仍然不支持递归。(某些语言的正则表达式引擎可以......但您要求用 Java 提供解决方案。)


您可以创建一个正则表达式来处理有限数量的嵌套括号级别,但它会变得丑陋且效率低下......特别是如果您必须处理不平衡括号的错误输入!(并且效率问题也适用于涉及递归正则表达式的假设解决方案......)

但是,我建议对字符串进行标记并进行简单的临时解析,计算括号级别并在级别返回零时发出结果。这是一个简单的编码问题:请参阅@Evgeniy Dorofeev 的答案作为起点。(但请注意,他没有处理 2 个错误案例......)

于 2013-01-15T06:25:48.717 回答
0

我不认为你可以用正则表达式来做到这一点。但是,如果您对其他解决方案感兴趣,我可以建议

    String s = "{{ info {{ abc}} {{ last}} }} {{ fast}}";
    List<String> l = new ArrayList<>();
    StringBuilder sb = new StringBuilder();
    int balance = 0;
    for(char c : s.toCharArray()) {
        sb.append(c);
        if (c == '{') {
            balance++;
        } else if (c == '}' && --balance == 0) {
            l.add(sb.toString());
            sb.setLength(0);
        }
    }
    System.out.println(l);

输出

[{{ info {{ abc}} {{ last}} }},  {{ fast}}]
于 2013-01-15T06:43:12.000 回答