那些年我們一起走過的正則表達式的坑


一、為什么需要學習正則表達式

正則表達式是一種應用廣,靈活度高的一種查找方式,目前在爬蟲爬取,對特定的內容的抓包,登錄的驗證等多個方面都用得上正則表達式,正是因為其極高的靈活度,所以也會給我們的使用帶來一定的麻煩,同時也提高了我們開發的復雜程度,復雜程度主要表現在語法上的不便記憶和應用層面上的易出錯,今天我們就來談談正則表達式在應用層面上常出現的錯誤

二、正則表達式常見坑與注意點

1、零寬斷言理解錯誤

零寬斷言匹配的相當於是一個位置,不是一個具體的內容

示例:

將字符串str="test.com"的.前面的替換為1,也就是str="1.com"

錯誤示范:

    var str="test.com"; console.log(str); var reg=/(?=\.)*/gi; //var re=new RegExp(reg); str=str.replace(reg,"1"); console.log(str);

運行結果是:str="1t1e1s1t1.1c1o1m",我想此時你的心情一定是這樣的

 從這個運行結果來看,就是在原來的字符串中的每個字符前面插入1,但是這個並不是我們所要求的,造成這樣的原因主要是位置弄錯了,現在把代碼改為如下所示:

 

var str="test.com"; console.log(str); var reg=/\w+(?=\.)/gi; //var re=new RegExp(reg); str=str.replace(reg,"1"); console.log(str);

 

這樣運行一下就得到了我們所要求的,這個位置我們其實是要求:零寬斷言+匹配類型+元字符+零寬斷言,錯誤示范中是零寬斷言+元字符這樣的一種組合,根本不符合語法的要求,所以錯誤。但是里面除了匹配類型是一定要存在的,其余的都可以按要求省去,也就是說不是必須的

 2、后向調用理解錯誤

示例

匹配字符串str="455 33"

錯誤示范

var str="455 33"; var test=/\b([1-4]\d{1,2})\s?\1\b/gi; console.log(test.test(str));

這個錯誤主要的原因是對后向調用的理解有誤,后向調用第n次使用時匹配第一次的完全相同的內容,但是不意味着在這里第二次引用前面分組的正則表達式,所以這里只匹配“455 455”這樣的字符串

 

對了這里里面的/g指的是全局匹配也就是在傳入中的全部內容進行搜索,如果不設置的話那么就返回第一個匹配的內容,/i也就是忽略大小寫的意思,除了這兩個外還有/m,表示多行匹配,什么是多行匹配呢?就是匹配換行符兩端的潛在匹配。影響正則中的^$符號

 3、全局變量的導向錯誤

這個錯誤不知道怎么說,但就是挺奇葩的,知道的人麻煩再下面留言一下

示例:

將.號前面的內容替換為"t",字符串為"dd1.432"

錯誤示范:

var str="dd1.432"; var reg=/\w*?(?=\.)/gi; str=str.replace(reg,"t"); console.log(str);

 

 這個時候原本你會以為正確運行但是,出現的效果確實“tt.432”,頓時你的內心一定是跟博主一樣有千萬只草泥馬在奔騰

但是最后的調試結果確實把最后面的g去掉,或者是修改為下面這樣

var str="dd1.432"; var reg=/^\w*?(?=\.)/gi; str=str.replace(reg,"t"); console.log(str);

 

4、對^ $理解上的錯誤

示例:

將上題修改為如下所示

錯誤示范:

var str="asdf dd1.432"; var reg=/^\w*?(?=\.)/gi; str=str.replace(reg,"t"); console.log(str);

 

^匹配的是傳入的字符串str的最開始的部分,$匹配的是str字符串最后的部分,如果是中間就不能使用這兩個限定,還好這個坑,博主不曾踩過

5、獲取某個DOM節點下面的內容

示例:

獲取標簽<ul>下面的內容,具體是str="<ul>  leslie</ul><ul>  謝燦勇</ul>"

 JavaScript代碼

 

var str="<ul>  leslie</ul><ul>  謝燦勇</ul>";
var reg=/(?<=<ul>)[\s\S]*?(?=</ul>)/g;
str=str.replace(reg,"t");
console.log(str);

 

運行的結果是:

這里面為什么會出現這樣的情況,相信此時你的內心也是奔潰的,猶如千萬只草泥馬呼嘯而過

經過了大量的試驗驗證,發現竟然是由於JavaScript中的正則表達式支持的相對比較少,所以也就沒有支持零寬度正回顧后發斷言[(?<=<ul>)],而且里面還存在另外的一個錯誤就是“/”是需要進行轉義操作的,但是這個時候我們發現要獲取<ul>位置后面的內容好像沒有方法可以實現了,經過了思考,我選擇了多次匹配來實現

6、多次匹配

接上面的問題繼續說下,我們所說的多次匹配其實就是第一次就只實現一部分,第二層次再實現一部分,這樣一直下去,直到完成。

我們第一次就只實現將</ul>去掉,然后將<ul>去掉,這樣就得到我們所要求的

 

var str="<ul>    leslie </ul><ul>  xiecanyong</ul>";
var reg=/<ul>[\s\S]*?(?=<\/ul>)/gi;
str=str.match(reg);
var reg1=/<ul>/i;
for(var i=0,max=str.length;i<max;i++){
    str=str.replace(reg1," ");
console.log(str);

}

 

第一次實現的代碼是這樣的,但是一運行卻發現只打印出leslie,這里主要的原因是,第一次就將leslie存入str變量中,然后第二次調用時,str=“leslie”,所以根本獲取不到<ul>,所以根本就是為空,所以也就只匹配到leslie,將代碼修改為如下就可以正常運行了

 

var str="<ul>    leslie </ul><ul>  xiecanyong</ul>";
var reg=/<ul>[\s\S]*?(?=<\/ul>)/gi;
str=str.match(reg);
var reg1=/<ul>/i;
for(var i=0,max=str.length;i<max;i++){
    str[i]=str[i].replace(reg1," ");
console.log(str[i]);
}

 

 打印一下結果:

 好的問題完成了,哈哈,內心如釋重負

7、多次匹配實現思路

其實在上面的內容中已經實現了兩種常見的多次匹配的思想,一種是獲取我們所要求的[str=str.match(reg)],另一種是將我們要除去的東西替換為空[ str[i]=str[i].replace(reg1," ")]所示

 三、總結

 通過這篇文章主要是希望大家能夠學習到一些在JavaScript中你可能會遇到的一些坑,以及一些問題的實現思路,如果在這里有什么地方說錯的,歡迎大家幫忙指正,在此不勝感激,如果你覺得這篇文章對你有幫助的話請為我點一個贊,你的點贊是我前進的動力。后續如果是大家有什么問題的話,也歡迎大家留言共同探討


免責聲明!

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



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