我有一个带有一些标记的字符串,看起来像这样:

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,旨在使正则表达式更具可读性以进行维护。

10-06 05:32
查看更多