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 交互的麻烦要少得多,但是请参阅诸如How should I call a Perl Script in Java?之类的答案。如果那是你想要做的。