如果我运行此命令:
/([^\/]+)+/g.exec('/a/b/c/d');
我得到这个:
["a", "a"]
但是如果我运行这个:
'/a/b/c/d'.match(/([^\/]+)+/g);
然后,我得到了预期的结果:
["a", "b", "c", "d"]
有什么不同?
+
不需要第二个,因为match
它将已经返回所有子表达式。.exec
每次仅返回一个,因此也不需要+
。
如果我运行此命令:
/([^\/]+)+/g.exec('/a/b/c/d');
我得到这个:
["a", "a"]
但是如果我运行这个:
'/a/b/c/d'.match(/([^\/]+)+/g);
然后,我得到了预期的结果:
["a", "b", "c", "d"]
有什么不同?
+
不需要第二个,因为match
它将已经返回所有子表达式。.exec
每次仅返回一个,因此也不需要+
。
Answers:
exec
带有全局正则表达式的表达式应在循环中使用,因为它仍将检索所有匹配的子表达式。所以:
var re = /[^\/]+/g;
var match;
while (match = re.exec('/a/b/c/d')) {
// match is now the next match, in array form.
}
// No more matches.
String.match
为您执行此操作,并丢弃捕获的组。
while(match = /[^\/]+/g.exec('/a/b/c/d')
,否则将创建无限循环!因为它是在MDN明确提出developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
new RegExp("pattern")
与ES5之前的/pattern/
含义不同。
一张照片更好,你知道...
re_once = /([a-z])([A-Z])/
re_glob = /([a-z])([A-Z])/g
st = "aAbBcC"
console.log("match once="+ st.match(re_once)+ " match glob="+ st.match(re_glob))
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st))
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st))
看到不同?
注意:要突出显示,请注意在匹配的模式(例如:aA)之后返回捕获的组(例如:a,A),而不仅仅是匹配的模式。
如果您的正则表达式是全局的,并且正在捕获,则必须使用exec。匹配不会返回您的所有捕获。
匹配非常适合仅匹配(不捕获)的情况。您运行一次,它将给出所有匹配项的数组。(尽管如果正则表达式不是全局的,则match将显示匹配项,然后是捕获)
Exec是捕获时使用的,每次执行时都会给出匹配项,然后是捕获。(只有当正则表达式不是全局的时,匹配才会以完全匹配后再捕获的方式运行)。
Exec的另一个用途是获取匹配项的索引或位置。当您的正则表达式具有变量时,可以使用.lastIndex并获取匹配项的位置。一个正则表达式对象具有.lastIndex,而正则表达式对象就是您对.exec执行的操作。点匹配是在字符串上完成的,您将不能再执行正则表达式对象点lastIndex
一个字符串,具有match函数,该函数传递一个正则表达式。还有一个正则表达式,具有exec函数,并传递了一个字符串
exec您运行了多次。匹配你跑一次
最好在不捕获时使用match,并且捕获时可以使用exec,它更强大,因为它对获取捕获很有用,但是如果在捕获时确实使用match,则看到它在正则表达式不是全局的时显示捕获。当正则表达式为全局时,不显示捕获。
> "azb".match(/a(z)b/);
[ "azb", "z" ]
> "azb".match(/a(z)b/g);
[ "azb" ]
>
另一件事是,如果您使用exec,请注意它是在正则表达式上调用的,那么,如果您为正则表达式使用了变量,则您将拥有更多的功能
当您不使用正则表达式变量时,您不会得到匹配项,因此当使用exec时,请使用变量用于正则表达式
> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
> /./g.exec("abc")
[ "a" ]
>
> /[a-c]/g.exec("abc")
[ "a" ]
> /[a-c]/g.exec("abc")
[ "a" ]
>
> var r=/[a-c]/g
> r.exec("abc")
[ "a" ]
> r.exec("abc")
[ "b" ]
> r.exec("abc")
[ "c" ]
> r.exec("abc")
null
>
使用exec,您可以获得比赛的“索引”
> var r=/T/g
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
2
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
6
> r.exec("qTqqqTqqTq");
[ "T" ]
> r.lastIndex
9
> r.exec("qTqqqTqqTq");
null
> r.lastIndex
0
>
因此,如果您要索引或捕获,请使用exec(请记住,如您所见,使用“索引”,它给出的“索引”实际上是第n次出现,它是从1开始计数的。因此,您可以得出适当的减去1即可得到索引。如您所见,它给出0-lastIndex为0-未找到)。
而且,如果您想扩展匹配,则可以在捕获时使用它,但是当正则表达式是全局的时不能使用它,并且当您这样做时,数组的内容不是全部匹配,而是完整的匹配,然后是捕获。
r.lastIndex
是理解的区别的关键因素exec
和match
。
If your regex is global, and you are capturing, then you must use exec. Match won't return all your captures.
我在控制台上找到了它。只需复制/粘贴"a,b,c,aa,bb,cc".match(/(\w+)/g);
Opera,Firefox。
"a,b,c,aa,bb,cc".match(/(\w+)/g)
,正在发生的事情也显示了所有匹配,并且恰好您捕获了每个匹配,所以如果要显示所有捕获,它将看起来完全相同(cntd)
该.match()函数str.match(regexp)
将执行以下操作:
g
标志:它将返回所有子字符串(忽略捕获组)g
标志未在正则表达式中使用:它将返回与regexp.exec(str)
null
使用标志的.match()的示例g
:
var str = "qqqABApppabacccaba";
var e1, e2, e3, e4, e5;
e1 = str.match(/nop/g); //null
e2 = str.match(/no(p)/g); //null
e3 = str.match(/aba/g); //["aba", "aba"]
e4 = str.match(/aba/gi); //["ABA", "aba", "aba"]
e5 = str.match(/(ab)a/g); //["aba", "aba"] ignoring capture groups as it is using the g flag
和.match()无g
标识等同于.exec() :
e1=JSON.stringify(str.match(/nop/))===JSON.stringify(/nop/.exec(str)); //true
//e2 ... e4 //true
e5=JSON.stringify(str.match(/(ab)a/))===JSON.stringify(/(ab)a/.exec(str)); //true
该.exec()函数regexp.exec(str)
将执行以下操作:
g
标志:它将返回(每次调用时):下一个匹配项:。重要提示:如果正则表达式对象未存储在变量中(它必须是同一对象),则它将不会进入下一个匹配项[N_MatchedStr, N_Captured1, N_Captured2, ...]
N
g
标志未在正则表达式中使用:它将返回与具有g
标志一样并且第一次被调用且仅被调用一次的结果。null
.exec()的示例(存储的regexp +使用g
标志=每次调用都会更改):
var str = "qqqABApppabacccaba";
var myexec, rgxp = /(ab)a/gi;
myexec = rgxp.exec(str);
console.log(myexec); //["ABA", "AB"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "ab"]
myexec = rgxp.exec(str);
console.log(myexec); //null
//But in this case you should use a loop:
var mtch, myRe = /(ab)a/gi;
while(mtch = myRe.exec(str)){ //infinite looping with direct regexps: /(ab)a/gi.exec()
console.log("elm: "+mtch[0]+" all: "+mtch+" indx: "+myRe.lastIndex);
//1st iteration = elm: "ABA" all: ["ABA", "AB"] indx: 6
//2nd iteration = elm: "aba" all: ["aba", "ab"] indx: 12
//3rd iteration = elm: "aba" all: ["aba", "ab"] indx: 18
}
的实例.exec()当它不与每个呼叫改变:
var str = "qqqABApppabacccaba", myexec, myexec2;
//doesn't go into the next one because no g flag
var rgxp = /(a)(ba)/;
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
myexec = rgxp.exec(str);
console.log(myexec); //["aba", "a", "ba"]
//... ["aba", "a", "ba"]
//doesn't go into the next one because direct regexp
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
myexec2 = /(ab)a/gi.exec(str);
console.log(myexec2); //["ABA", "AB"]
//... ["ABA", "AB"]
exec
获取所有子选择。