js 正則 exec() 和 match() 數據抽取

                                                             js 正則 exec() 和 match() 數據抽取

轉載地址:js 正則 exec() 和 match() 數據抽取 去看看

js 的正則表達式平常用的不多,但以前抽取數據的時候用到過,主要是有這樣的需求;

var text='<td class="data">2014-4-4</td><br /><td class="data">2014-4-5</td>';
//希望輸出 ["2014-4-4", "2014-4-5"]

難倒不難,如何比較好的實現是個問題;

如果要提取其中的數據,主要就是 String 對象的 match()、replace()、split() 方法或者 RegExp 對象的 exec(),但是應用的時候,還是有點坑的;

首先寫出正則,這個不難,一個非全局,一個全局:

var re = /<td[^>]*?>([\s\S]*?)<\/td>/,
    reg = /<td[^>]*?>([\s\S]*?)<\/td>/g;

但是匹配多個 <td></td> 的時候,match 方法有點特殊:

image

match 的特殊在於:

非全局正則,可以返回捕獲組,也就是正則裏面()裏面的內容,但不能多次匹配;

全局正則,可以多次匹配,但不返回捕獲組;

實際上,如果全局正則,多次匹配還返回捕獲組的話,返回的數據就不可能是個簡單數組了,因爲 n 次匹配,m 個捕獲組,那返回的結果就是,數組裏有 n 個匹配結果,每個匹配結果裏,還要放一個數組,用來表示每個捕獲組的值;

如果換成 exec(),結果如下:

image

exec() 特殊在於:

不管正則是否加全局,返回的內容是一樣的

具體實現:

1、這裏,我們先用 match 實現一遍,按照前面的思路,就是用全局正則 match 一下,然後再遍歷獲取到的數組,通過非全局正則捕獲我們要的東西:

text.match(reg).map(function(v) {
    return v.match(re)[1];
});
//返回 ["2014-4-4", "2014-4-5"]

比較好理解,但是需要兩個正則,一個全局,一個非全局;

2、如果用 exec(),

var temp = [],data = [];
while ((temp = reg.exec(text)) !== null) {
    data.push(temp[1]);
}
//data:["2014-4-4", "2014-4-5"]

這樣寫的原因是,RegExp 對象的方法,經常有 lastIndex 的屬性,exec() 在執行的時候,實際上每回只匹配一次,然後改了 lastIndex 屬性的值爲下一個開始的地方,然後下次從新的地方開始再匹配,如果匹配到末尾匹配不到了,返回 null ,舉個例子:

image

這個特性不注意會被坑的,比如:

var reg=/ja/g,text='ja';
reg.test(text); //true reg.lastIndex 返回 2,其實也就是匹配到末尾了
reg.test(text); //false reg.lastIndex 返回 0,匹配到末尾沒匹配到,返回 null,lastIndex 重置爲 0;

參考資料:

JavaScript權威指南-第6版

JavaScript高級程序設計-第3版

行文倉促,如有錯誤,歡迎批評指正~~~
轉載請註明來源,文中所提文檔可以在我的 Github 上下載~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章