0

我正在阅读一个维基百科 XML 文件,我必须在其中删除大括号之间的任何内容。例如对于以下字符串:

String text = "{{Use dmy dates|date=November 2012}} {{Infobox 音乐艺术家 <!-- 参见 Wikipedia:WikiProject_Musicians --> | name
= 拉斯康威 | 图像 = | 标题 = Russ Conway,在他 1959 年 [[Extended play|EP]] ''More Party Pops'' 的正面照片。| 图像大小 = | 背景 = non_vocal_instrumentalist | birth_name = 特雷弗·赫伯特·斯坦福 | 别名 = | 出生日期 = {{出生日期|1925|09|2|df=y}} | birth_place = [[布里斯托]],[[英格兰]],英国 | death_date = {{死亡日期和年龄|2000|11|16|1925|09|02|df=y}} | death_place = [[伊斯特本]],[[苏塞克斯]],英格兰,英国 | 原产地 = | 乐器 = [[钢琴]] | 流派 = | 职业 = [[音乐家]] | 年活跃= | 标签 = EMI(哥伦比亚)、Pye、MusicMedia、丘吉尔 | 关联行为 = | 网站 = | notable_instruments = }}";

它应该替换为一个空字符串。请注意,该示例有多个新行并嵌套了 {{...}}

我正在使用以下代码:

Pattern p1 = Pattern.compile(".*\\({\\{.+\\}\\}).*", Pattern.DOTALL);
Matcher m1 = p1.matcher(text);

while(m1.find()){

String text1 = text.replaceAll(m1.group(1), "");
}

我是正则表达式的新手,你能告诉我我做错了什么吗?

4

1 回答 1

1

这对于正则表达式通常是不可能的。常规语言无法描述任意级别的嵌套,因为它们无法“计算”它们所处的级别。

如果您绝对必须使用正则表达式,您可以通过手动编码所有嵌套可能性来创建一个繁琐的表达式,该表达式最多可用于三层嵌套。但这将非常繁琐,实际上违反了 DRY,并且远不是适合这项工作的正确工具。

如果需要,“手动”执行此操作可能会更容易。自己扫描字符串,每次击中{{增加“大括号级别”;每次你打一个}}减少它。当且仅当大括号级别为零时,将每个字符复制到输出。

类似(未经测试):

StringBuilder output = new StringBuilder();
char[] input = text.toCharArray();
int braceLevel = 0;
for (int i = 0; i < input.length; i++) {
   final char c = input[i];
   if (c == '{') {
      // Check for {{
      if (i < input.length - 1 && input[i+1] == '{') {
         // Yep, it's a double brace - increase the level, consume
         // the second character and continue with the next char
         braceLevel++;
         i++;
         continue;
      }
   }
   else if (c == '}' && braceLevel > 0) {
      // Check for a closing brace similar to above
      if (i < input.length - 1 && input[i+1] == '}') {
         braceLevel--;
         i++;
         continue;
      }
   }

   if (braceLevel == 0) {
      output.append(c);
   }
}

// Now output contains every character that was not contained within brackets
于 2013-10-03T11:58:48.123 回答