JS正則匹配過濾字符串中的html標簽及html標簽內的內容


使用正則過濾html標簽。

以前寫了很多次。但每次都沒保存,然后換了家公司后,沒有了以前的代碼,然后又遇到類似的問題,然后又是網上查啊寫啊,自己鼓搗了大半天。

所以,這次,我決定在博客上也寫一份,備份,省的下次又自己寫一次,浪費我的腦細胞。

 

一、匹配html標簽,但不匹配html標簽里的內容(簡單粗暴,直接上正則。前面三種不是我所需要的,后面reg4過濾單標簽的,可以需要)

 var reg =  /<[^>]+>/gi;                  //匹配所有的html標簽。但不包括html標簽內的內容
 var reg2 = /<(?!img).*?>/gi;             //匹配除img標簽外的html標簽  不包括html標簽內的內容
 var reg3 = /<(?!img|p|\/p).*?>/gi;       //匹配除img、p標簽外的html標簽  不包括html標簽內的內容
 var reg4 = /<(img|br|hr|input)[^>]*>/gi;          //只匹配img、br、hr、input標簽

二、匹配html標簽里內容的正則,有兩大難點

  1、單標簽和雙標簽的區別 例如 <br><img> 和 <div></div> 的區別

  2、嵌套標簽(超難,基本無解,若需要過濾的話,則可以通過分組匹配一直重復匹配來解決) 例如 <div>外面的div<div>里面的div</div></div>

 

思路:

先用下面的正則把所有的單標簽去除:

var reg = /<(img|br|hr|input)[^>]*>/gi;

再上基本的正則匹配代碼:

  /*
    * 普通匹配  (但后面用不到,用不到的原因,可查看下面截圖)
    * 下面兩個可以匹配
    * 但是有個bug  嵌套標簽的結構就不會被匹配到      例如這樣的結構: <div>外面的div<div>里面的div</div></div>
    * 這也就是上面所說的嵌套標簽的難點
    * */
    var reg = /<div[^>]*>[^<]*<\/div>/gi;    //匹配所有的div標簽。包括div標簽內的內容
    var reg2 = /<[^>]*>[^<]*(<[^>]*>)?/gi;   //匹配所有的html標簽,包括html標簽內的內容


    /*
    * 使用分組匹配
    * bug跟上面的一樣     嵌套標簽的結構就不會被匹配到      例如這樣的結構: <div>外面的div<div>里面的div</div></div>
    * 如果用在過濾上的話,可以重復過濾(不會少過濾掉一些本就在標簽內的內容,也不會多過濾標簽外的內容)。在過濾上看,分組匹配比上面的匹配靠譜多了。
    * 但是,有個小問題,下面的分組匹配正則匹配不到單標簽的,所以還需要用到上面的一般匹配。
    * 雙標簽對應匹配
    * */
    var reg3 = /<(div)[^>]*>[^<]*<\/(\1)>/gi;  //分組匹配   匹配所有的div標簽,包括div標簽內的內容
    var reg4 = /<(\S*)[^>]*>[^<]*<\/(\1)>/gi;   //分組匹配   匹配所有的html雙標簽,包括div標簽內的內容

再分析上面的兩個匹配:

  普通匹配,可以匹配到單標簽和雙標簽,但是嵌套標簽,這就問題大了,看下面截圖

  分組匹配,只能匹配雙標簽,但是嵌套標簽,有點小問題,但可以接受,可以用循環來匹配,看下面截圖

 

這思路寫的不好,不喜勿噴,也希望正則大佬留下說出新的想法。

 

最終代碼:

/*
* 在網上看到用 new RegExp() 比 正則字面量  速度快
* 網址:https://www.cnblogs.com/52cik/p/js-regular-literal-regexp.html
* 我沒測試過,姑且一試,以后有機會弄個測試出來
* */

/*
* 正則放定義的原因:
* 是我不想在函數里重復定義正則,比較損性能,但如果不是多次使用級別的,那也損不了多少性。
* */
// var reg =  /<[^>]+>/gi;  //過濾所有的html標簽
var reg =  new RegExp('<[^>]+>','gi');  //過濾所有的html標簽,不包括內容

// var reg2 = /<(img|br|hr|input)[^>]*>/gi;  //只匹配img、br、hr、input標簽
var reg2 = new RegExp('<(img|br|hr|input)[^>]*>','gi');  //只匹配img、br、hr、input標簽

// var reg3 = /<(\S*)[^>]*>[^<]*<\/(\1)>/gi;        //分組匹配,過濾所有的html標簽,包括內容
var reg3 = new RegExp('<(\\S*)[^>]*>[^<]*<\\/(\\1)>','gi');  //分組匹配,過濾所有的html標簽,包括內容



/*
* 將所有的標簽過濾,不過濾標簽內內容
* */
function filterHtml(str){
    if(typeof str !='string'){  //不是字符串
        return str;
    }

    return str.replace(reg,'');
}

/*
* 講所有的標簽過濾,也過濾標簽內的內容
* str 需要過濾的字符串
* isbool  為false則需要單標簽過濾,為true則不需要單標簽過濾
* */
function filterHtmlOrContainer(str,isbool) {
    if(typeof str !='string'){  //不是字符串
        return str;
    }
    var result = str;
    if(!isbool){  //先把單標簽過濾了
        result = result.replace(reg2, '');
    }
    result = result.replace(reg3,'');    //先經過分組匹配,把雙標簽去除,如果是嵌套標簽,則會先將嵌套標簽內的雙標簽過濾掉
    if(reg3.test(result)) { //如果為true,則代表還有標簽
        return filterHtmlOrContainer(result, true);
    }else {
        return result;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM