Java:正则表达式删除XML文件的一部分

时间:2013-10-03 11:33:30

标签: java regex parsing wikitext

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

  

String text =“{{Use dmy dates | date = November 2012}} {{Infobox musical   艺术家<! - 参见维基百科:WikiProject_Musicians - > |命名
  = Russ Conway | image = | caption = Russ Conway,照片出现在他的1959年[[扩展游戏| EP]]''更多   派对流行''。 | image_size = | background =   non_vocal_instrumentalist | birth_name =特雷弗赫伯特   斯坦福大学|别名= | birth_date = {{birth   日期| 1925 | 09 | 2 | df = y}} | birth_place = [[Bristol]],   [[英格兰]],英国| death_date = {{死亡日期和   年龄| 2000 | 11 | 16 | 1925 | 09 | 02 | df = y}} | death_place =   [[Eastbourne]],[[Sussex]],英国,英国| origin = |   乐器= [[钢琴]] |流派= |占用   = [[音乐家]] | years_active = | label = EMI(哥伦比亚),Pye,MusicMedia,丘吉尔| associated_acts = |   网站= | notable_instruments =}}“;

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

我使用以下代码:

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

while(m1.find()){

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

我是regex的新手,你能告诉我我做错了什么吗?

1 个答案:

答案 0 :(得分: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