由于作一道题(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