2014-01-30 48 views
0

意識到所有的SO answers that warn against Regex to parse html我有一種場景,解析器和DOM技巧是不可能的,需要使用正則表達式來刪除標記和具有定義文本的內容值。例如在:使用正則表達式從html中刪除匹配文本忽略內部鏈接標記的href鏈接

<div>foo bar</div 
<a href="http://example.com">some text</a> 
<div>foo bar foo bar</div> 

我目前使用此功能來解析出符合要求的鏈接

/** 
* Removes links from html text 
* @param {string} html The html to be cleaned. 
* @param {string} exclude The string of link text to remove. 
* @returns {string} Cleaned html. 
*/ 
function cleanBody(html, exclude){ 
    html = html.replace(/\r?\n|\r|\t|/g, ''); 
    var re = '<a\\b[^>]*>('+exclude+')<\\/a>'; 
    return html.replace(new RegExp(re,'ig'),""); 
} 

在上面的例子中我會通過HTML和字符串「一些文本」將其刪除。這適用於我的方案,直到包含其他標記,例如

<div>foo bar</div 
<a href="http://example.com"><font color="#1122cc">some text</font></a> 
<div>foo bar foo bar</div> 

我該如何改進正則表達式(或函數)來說明額外的標記(不使用DOM,jQuery或其他庫)?

+1

*解析器和DOM技巧爲什麼不可能*? – MCL

+0

如何創建一個獨立的div元素並將它的'innerHTML'屬性設置爲字符串?這對你有用嗎?你想要瞄準什麼「額外的標記」? – MaxArt

+0

@MCL我正在使用Google Apps腳本,該腳本使用JavaScript語法,但在服務器端執行https://developers.google.com/apps-script/ – mhawksey

回答

1

下面的正則表達式應該爲你提供的特定情況下工作:

var re="<a\\b[^>]*>(<[^>]+>)*("+exclude+")(<(?!/a>)[^>]+>)*</a>"; 
  • 比賽的開幕錨標記後,添加匹配零個或多個標籤的模式,無論是打開的標籤或結束標記,有效或無效:(<[^>]+>)*
  • 匹配排除文本後,添加匹配零個或多個標記的模式,無論它們是打開標記還是結束標記,有效還是無效,但是 - 使用負向預測 - 與結束錨點標記不匹配:(<(?!/a>)[^>]+>)*

請認識到這個正則表達式在它的工作方式上還不是很「聰明」。它不會嘗試匹配平衡的標籤或過濾無效有效的標籤名稱,所以下面無效的HTML將被匹配:

<a href="http://example.com">some text</font></span></div></a> 
<a href="http://example.com"><div>some text</font></span></div></a> 
<a href="http://example.com"><foo>some text</div></a> 

另外,請注意以下無效HTML匹配最多隻能收錨標籤

<a href="http://example.com"><div>some text</font></a></div> 

收盤</div>不會匹配。

小心嵌套的錨點。下面將匹配(注意,只有一個關閉錨標記匹配):

<a href="http://foo.org"><a href="http://example.com">some text</a> 

可能有意外這個模式,我沒有想到的匹配其他數據。

另一方面,嵌套標籤不必包裝排除文本。下面將匹配:

<a href="http://example.com"><span></span>some text<div></div></a> 
<a href="http://example.com">some text<font></font></a> 

有使正則表達式多一點靈活的和/或安全的機會不多,但是這超出你問的範圍。

相關問題