[英]Java regex to match all html elements except one special case
我有一个带有一些标记的字符串,如下所示:
The quick brown <a href="www.fox.org">fox</a> jumped over the lazy <a href="entry://id=6000009">dog</a> <img src="dog.png" />.
我试图去除除了锚点元素之外的所有内容,其中包含“entry:// id =”。 因此,上述示例的所需输出将是:
The quick brown fox jumped over the lazy <a href="entry://id=6000009">dog</a>.
写这场比赛,我到目前为止最接近的是:
<.*?>!<a href=\\"entry://id=\\\\d+\\">.*?<\\\\/a>
但我无法弄清楚为什么这不起作用。 任何帮助(除了“为什么你不使用解析器”:)将不胜感激!
我真的不会使用正则表达式来解析HTML。 HTML并不是常规的,并且没有结束边缘情况会让你失望。
请查看JTidy 。
正则表达式不容易实现。 我推荐一个理解HTML / XML语义的解析器。
如果你坚持 ,你可以做一个多步骤的方法,如:
"<(a\\s*href="entry:.*?/a)>"
替换为"{{{{\\1}}}}"
"<(?!/a}}}})[^>]*>"
替换为""
"{{{{"
替换为"<"
"}}}}"
替换为">"
请注意,上述内容容易出错,并且会在某些时候失败。 认为它是一个丑陋的黑客,而不是一个真正的解决方案。 像上面这样的东西可以在一个正则表达式的文本编辑器中对一些文本文件进行一次性编辑,但是对于在应用程序中作为数据处理的一部分重复,真实地使用 - 不是那么多。
使用这个:
((<a href="entry://id=\d+">.*?</a>)|<!\[CDATA\[.*?\]\]>|<!--.*?-->|<.*?>)
并将它与替换所有$ 2相结合将适用于您的示例。 下面的代码证明了这一点:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.*;
import org.junit.Test;
public class TestStack1305864 {
@Test
public void matcherWithCdataAndComments(){
String s="The quick <span>brown</span> <a href=\"www.fox.org\">fox</a> jumped over the lazy <![CDATA[ > ]]> <a href=\"entry://id=6000009\">dog</a> <img src=\"dog.png\" />.";
String r="The quick brown fox jumped over the lazy <a href=\"entry://id=6000009\">dog</a> .";
String pattern="((<a href=\"entry://id=\\d+\">.*?</a>)|<!\\[CDATA\\[.*?\\]\\]>|<!--.*?-->|<.*?>)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(s);
String t = s.replaceAll(pattern, "$2");
System.out.println(t);
System.out.println(r);
assertEquals(r, t);
}
}
我们的想法是捕获您有兴趣保留在特定组中的所有元素,以便将它们插回到字符串中。
这样你可以替换所有:
对于与有趣的元素不匹配的每个元素,该组将为空,并且元素将替换为“”
对于有趣的元素,该组不会为空,并将附加到结果String。
编辑:处理CDATA中的嵌套<或>和注释
编辑:请参阅http://martinfowler.com/bliki/ComposedRegex.html获取正则表达式组合模式,旨在使正则表达式更易于维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.