[英]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.