1. 程式人生 > 程式設計 >js通過正則匹配沒有內容的空標籤

js通過正則匹配沒有內容的空標籤

js 如何正則匹配沒有內容的空標籤並移除掉?

例如

<span></span>

<p></p>

等等

正則

/<([a-z]+?)(?:\s+?[^>]*?)?>\s*?<\/\1>/ig

html='<div id="fixedTools" class="hidden-xs hidden-sm">'+
'\n  <a id="backtop" class="hidden border-bottom" href="#" rel="external nofollow" ></a>'+
'\n'+
'\n  <div class="qrcodeWraper">'+
'\n    <a href="/app#qrcode" rel="external nofollow" ><span class="glyphicon glyphicon-qrcode"></span></a>'+
'\n    <img id="qrcode" class="border" alt="sf-wechat" src="https://sf-static.b0.upaiyun.com/v-581fe7b0/page/img/app/appQrcode.png">'+
'\n'+
'\n    <p class="qrcode-text"></p>'+
'\n  </div>'+
'\n</div>'

ptn=/<([a-z]+?)(?:\s+?[^>]*?)?>\s*?<\/\1>/ig
s = html.replace(ptn,'')
console.log(s)

通過線上測試工具

js通過正則匹配沒有內容的空標籤

如果考慮將沒有style的span去掉

有span的就留下來

js通過正則匹配沒有內容的空標籤

因為預設編輯器中,span沒有樣式的沒有必要

str=str.replace(/<span\s*?(?!:style)>(.[^<>]*)<\/span>/ig,"$1");

先看下面的位置

零寬斷言
接下來的四個用於查詢在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b,^,$那樣用於指定一個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱為零寬斷言。最好還是拿例子來說明吧:

斷言用來宣告一個應該為真的事實。正則表示式中只有當斷言為真時才會繼續進行匹配。

(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的後面能匹配表示式exp。比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查詢I'm singing while you're dancing.時,它會匹配sing和danc。

(?<=exp)也叫零寬度正回顧後發斷言,它斷言自身出現的位置的前面能匹配表示式exp。比如(?<=\bre)\w+\b會匹配以re開頭的單詞的後半部分(除了re以外的部分),例如在查詢reading a book時,它匹配ading。

假如你想要給一個很長的數字中每三位間加一個逗號(當然是從右邊加起了),你可以這樣查詢需要在前面和裡面新增逗號的部分:((?<=\d)\d{3})+\b,用它對1234567890進行查詢時結果是234567890。

下面這個例子同時使用了這兩種斷言:(?<=\s)\d+(?=\s)匹配以空白符間隔的數字(再次強調,不包括這些空白符)。

負向零寬斷言
前面我們提到過怎麼查詢不是某個字元或不在某個字元類裡的字元的方法(反義)。但是如果我們只是想要確保某個字元沒有出現,但並不想去匹配它時怎麼辦?例如,如果我們想查詢這樣的單詞--它裡面出現了字母q,但是q後面跟的不是字母u,我們可以嘗試這樣:

\b\w*q[^u]\w*\b匹配包含後面不是字母u的字母q的單詞。但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發現,如果q出現在單詞的結尾的話,像Iraq,Benq,這個表示式就會出錯。這是因為[^u]總要匹配一個字元,所以如果q是單詞的最後一個字元的話,後面的[^u]將會匹配q後面的單詞分隔符(可能是空格,或者是句號或其它的什麼),後面的\w*\b將會匹配下一個單詞,於是\b\w*q[^u]\w*\b就能匹配整個Iraq fighting。負向零寬斷言能解決這樣的問題,因為它只匹配一個位置,並不消費任何字元。現在,我們可以這樣來解決這個問題:\b\w*q(?!u)\w*\b。

零寬度負預測先行斷言(?!exp),斷言此位置的後面不能匹配表示式exp。例如:\d{3}(?!\d)匹配三位數字,而且這三位數字的後面不能是數字;\b((?!abc)\w)+\b匹配不包含連續字串abc的單詞。

同理,我們可以用(?<!exp),零寬度負回顧後發斷言來斷言此位置的前面不能匹配表示式exp:(?<![a-z])\d{7}匹配前面不是小寫字母的七位數字。

一個更復雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標籤內裡的內容。(?<=<(\w+)>)指定了這樣的字首:被尖括號括起來的單詞(比如可能是),然後是.*(任意的字串),最後是一個字尾(?=<\/\1>)。注意字尾裡的\/,它用到了前面提過的字元轉義;\1則是一個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內容,這樣如果字首實際上是的話,字尾就是了。整個表示式匹配的是和之間的內容(再次提醒,不包括字首和字尾本身)。

這個解讀

1、<span後面的/s*? 主要是考慮<span >與<span>都考慮在內

\s匹配空字元*表示多個空字元都可以,?是表示前面的可有可無。

2、(?!:style) 表示右側不能有style的才可以匹配,因為有的肯定有用。而且不獲取,所以這個括號不是$1

3、(.[^<>]*) 就是匹配<span></span>中間的資料了。

這兩天剛開始研究這個,寫了好幾個正則,先分享出來,看大家能看懂嗎

//加強替換主要是考慮多個br的問題
function doRepAdvance(s){
var str=s.replace(/<p><br type="_moz">\s*?<\/p>/ig,"");
str=str.replace(/<p>\s*<br type="_moz">\s*<\/p>/ig,"");
str=str.replace(/<p>\s*?<br\s?\/?>\s*?<\/p>/ig,"");
str=str.replace(/<p>(\s|\ \;| | |\xc2\xa0)*<\/p>/ig,"");
str=str.replace(/<p>\s*?<\/p>/ig,"");
str=str.replace(/<p><\/p>/ig,"");
str=str.replace(/<br type="_moz">\n<\/p>/ig,"</p>");
str=str.replace(/<br type="_moz">\s*?<\/p>/ig,"</p>");
str=str.replace(/<br\s?\/?>\s*?<\/p>/ig,"</p>");
str=str.replace(/<br \/>\n<\/p>/ig,"</p>");
str=str.replace(/<br>\n<\/p>/ig,"</p>");
//多個br
str=str.replace(/(<br type="_moz">\s*)+<\/p>/ig,"</p>");
str=str.replace(/(<br\s?\/?>\s*)+<\/p>/ig,"</p>");
//空標籤
str=str.replace(/<p style=["'].[^<>]*["']>/ig,"<p>");
str=str.replace(/<span style="background-color: initial;">/ig,"<span>");
//沒有style的span去掉
str=str.replace(/<span\s*?(?!:style)>(.[^<>]*)<\/span>/ig,"$1");
str=str.replace(/<([a-z]+?)(?:\s+?[^>]*)?>(\s|)*?<\/\1>/ig,"");
//str=str.replace(/<([a-z]+?)(?:\s+?[^>]*)?>\s*?<\/\1>/ig,"");

return str;
}

上面都是一些好東西,具體的自己研究吧。