JRegexは再帰的マッチングをサポートしていないようです。そのためjava.util.regex
、ネストのレベル数を使用して制限を設定することをお勧めします。
たとえば、各レベル(最も深いものを除く)に「無制限」の数のブラケットペアを使用して、最大50レベルのネストを許可するには、次のように使用できます。
// Set the maximum number of nested levels required.
int max = 50;
String regex = "(?R)";
while (--max > 0) {
regex = regex.replace("(?R)", "(?>\\{(?:[^{}]*+|(?R))+\\})");
}
// Ensure no (?R) in the final and deepest replacement.
regex = regex.replace("(?R)", "\\{[^{}]*+\\}") + "|\\w+";
String str = " {{}{}} {abc} {{de}{fg}} hij {1{2{3{4{5{6{7{8{9{10{11{12{13{14{15{16{17{18{19{20{21{22{23{24{25{26{27{28{29{30{31{32{33{34{35{36{37{38{39{40{41{42{43{44{45{46{47{48{49{50}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} {end}";
Matcher m = Pattern.compile(regex).matcher(str);
while (m.find()) {
System.out.println(m.group());
}
/*
{{}{}}
{abc}
{{de}{fg}}
hij
{1{2{3{4{5{6{7{8{9{10{11{12{13{14{15{16{17{18{19{20{21{22{23{24{25{26{27{28{29{30{31{32{33{34{35{36{37{38{39{40{41{42{43{44{45{46{47{48{49{50}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
{end}
*/
上記は、再帰的マッチングがサポートされている場合に使用できる正規表現を取得し、パターン全体(?>\\{(?:[^{}]*+|(?R))+\\})
を繰り返し置換することによって正規表現を構築します。(?R)
作成される式にはネストされた数量詞が多数あるため、アトミックグループ化(?>)
と所有格数量詞+
を使用して、バックトラッキングを制限し、一致するものが見つからない場合に正規表現が迅速に失敗するようにします。正規表現は長くなる可能性がありますが、効率的です。
ネストに制限を設定したくない、または設定できない場合、または長い正規表現のアイデアが心配な場合は、ファイルテキストを繰り返し処理し、開始ブラケットと終了ブラケットの数を追跡するだけで、ネストされたブラケットを解析できます。 、 例えば
List<String> list = new ArrayList<String>();
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
char c = str.charAt(i);
if (c == '{') {
int b = 1;
StringBuilder sb = new StringBuilder("{");
while (b > 0 && i < strLen - 1) {
sb.append( c = str.charAt(++i) );
if (c == '}') b--;
else if (c == '{') b++;
}
list.add(sb.toString());
}
}
for (String s : list) { System.out.println(s); }
これはPerlとの対話よりもはるかに少ない問題のように思えますが、「JavaでPerlスクリプトを呼び出すにはどうすればよいですか?」などの回答を参照してください。それがあなたがやりたいことなら。