由於作一道題(http://www.codewars.com/kata/insert-dashes/solutions/javascript),題目以下:javascript
Write a function insertDash(num) that will insert dashes ('-') between
each two odd numbers in num. For example: if num is 454793 the output
should be 4547-9-3. Don't count zero as an odd number.java
其中一個解答,引發了我對正則的研究興趣,解答以下:正則表達式
function insertDash(num) { return String(num).replace(/([13579])(?=[13579])/g, '$1-'); }
我對正則表達式中的 正向確定預查(?=pattern)
一直不帶明白,因此趁這個機會研究一下。數組
下面是個人測試代碼:測試
var str = "13579"; var regArr = [ /([13579])([13579])/g, // capturing groups /([13579])(?:[13579])/g, // non-capturing groups /([13579])(?=[13579])/g // Assertions ]; regArr.forEach(function(reg){ console.log("regexp:", reg); while((q=reg.exec(str)) != null){ console.log(q, "lastIndex", reg.lastIndex); } console.log("result:", str.replace(reg, "$1-")); });
測試代碼的輸出:code
regexp: /([13579])([13579])/g ["13", "1", "3", index: 0, input: "13579"] "lastIndex" 2 ["57", "5", "7", index: 2, input: "13579"] "lastIndex" 4 result: 1-5-9 regexp: /([13579])(?:[13579])/g ["13", "1", index: 0, input: "13579"] "lastIndex" 2 ["57", "5", index: 2, input: "13579"] "lastIndex" 4 result: 1-5-9 regexp: /([13579])(?=[13579])/g ["1", "1", index: 0, input: "13579"] "lastIndex" 1 ["3", "3", index: 1, input: "13579"] "lastIndex" 2 ["5", "5", index: 2, input: "13579"] "lastIndex" 3 ["7", "7", index: 3, input: "13579"] "lastIndex" 4 result: 1-3-5-7-9
regexObj.exec(str)
返回結果是一個數組,其中第一個成員是所匹配的字符串,接下來是捕獲的分組,它有一個index 屬性,代表是從哪一個地方開始匹配的。與此同時,reg 對象的 lastIndex 更新爲下一次開始匹配的索引值。regexp
/([13579])([13579])/g
每次匹配兩個字符,下次開始匹配位置 +2, 每次產生兩個捕獲分組;對象
/([13579])(?:[13579])/g,
每次也匹配兩個字符,下次開始匹配位置 +2, 因爲使用了非捕獲匹配,因此每次產生一個捕獲分組;索引
/([13579])(?=[13579])/g
, (?=[13579])
只幫助定位匹配的位置,並不屬於匹配的字符,因此每次匹配一個字符,因此下一次開始匹配位置 +1 ;ip