Java正则表达式保留特定的结束标记

时间:2010-02-02 22:33:56

标签: java regex

我正在尝试编写一个正则表达式来删除除少数几个关闭的xml标记之外的所有内容。

代码看起来很简单:

String stringToParse = "<body><xml>some stuff</xml></body>";
Pattern pattern = Pattern.compile("</[^(a|em|li)]*?>");
Matcher matcher = pattern.matcher(stringToParse);
stringToParse = matcher.replaceAll("");

然而,当它运行时,它会跳过“xml”结束标记。它似乎跳过了编译组中有匹配字符的任何标记(a | em | li),即如果我从“li”中删除“l”,它就可以工作。

我希望这会返回以下字符串:“<body><xml>some stuff”(我正在进行额外的解析以删除开始标记,但保持示例的简单)。

3 个答案:

答案 0 :(得分:4)

您可能不应该使用正则表达式执行此任务,但让我们看看会发生什么......

您的问题是您使用的是负字符类,而在字符类中,您无法编写复杂的表达式 - 只能使用字符。您可以尝试使用否定前瞻:

"</(?!a|em|li).*?>"

但这不能正确处理大量案件:

  • 包含看似标签的内容的评论。
  • 标记为属性中的字符串。
  • 以a,em或li开头的标签,但实际上是其他标签。
  • 大写字母。
  • 等...

您可以修复这些问题,但是您需要考虑它是否值得,或者是否最好根据适当的HTML解析器寻找解决方案。

答案 1 :(得分:1)

我真的会使用适当的解析器(例如JTidy)。您无法使用正则表达式解析XML / HTML,因为它不是常规的,并且没有边缘情况的结束。我宁愿使用标准JDK(JAXP)中提供的XML解析或合适的第三方库(见上文)并相应地配置输出。

有关更多热情信息,请参阅this answer。通过regexps解析XML / HTML。

答案 2 :(得分:0)

您不能在字符类中使用替换。字符类始终匹配单个字符。

您可能希望使用负向前瞻或后视:

"</(?!a|em|li).*?>"