2

次のようなマークアップを含む文字列があります。

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>

しかし、なぜこれが機能しないのかわかりません。どんな助けでも(「パーサーを使わない理由」を除いて:)大歓迎です!

4

3 に答える 3

7

HTML の解析に正規表現を使用することはありません。HTML は規則的ではなく、つまずくエッジケースが後を絶ちません。

代わりにJTidyをチェックしてください。

于 2009-08-20T12:36:09.853 に答える
1

これを使用して:

((<a href="entry://id=\d+">.*?</a>)|<!\[CDATA\[.*?\]\]>|<!--.*?-->|<.*?>)

それを replace all $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 およびコメント内のネストされた < または > を処理します

于 2009-08-20T13:37:32.437 に答える