我有一个带有一些标记的字符串,看起来像这样: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>
但是我不知道为什么这行不通。任何帮助(除了“为什么不使用解析器” :)都将不胜感激!
最佳答案
使用这个:
((<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);
}
}
这个想法是捕获所有您想要保留在特定组中的元素,以便您可以将它们重新插入字符串中。
这样,您可以替换所有:
对于与有趣元素不匹配的每个元素,组将为空,并且该元素将替换为“”
对于有趣的元素,该组将不会为空,并将添加到结果字符串中。
编辑:处理CDATA中的嵌套和注释
编辑:有关正则表达式组成模式的信息,请参见http://martinfowler.com/bliki/ComposedRegex.html,旨在使正则表达式更具可读性以进行维护。