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 に答える