如果我运行这个:
/([^\/]+)+/g.exec('/a/b/c/d');
我明白了:
["a", "a"]
但是如果我运行这个:
'/a/b/c/d'.match(/([^\/]+)+/g);
然后我得到了预期的结果:
["a", "b", "c", "d"]
有什么不同?
如果我运行这个:
/([^\/]+)+/g.exec('/a/b/c/d');
我明白了:
["a", "a"]
但是如果我运行这个:
'/a/b/c/d'.match(/([^\/]+)+/g);
然后我得到了预期的结果:
["a", "b", "c", "d"]
有什么不同?
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
为您执行此操作并丢弃捕获的组。
一张图更好,你知道...
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))
看到不同?
注意:要突出显示,请注意捕获的组(例如:a,A)在匹配的模式(例如:aA)之后返回,它不仅仅是匹配的模式。
如果您的正则表达式是全局的,并且您正在捕获,那么您必须使用 exec。匹配不会返回您所有的捕获。
Match 适用于仅匹配(不捕获)的情况。你运行一次,它会给出所有匹配的数组。(虽然如果正则表达式不是全局的,那么匹配将显示匹配后跟捕获)
Exec 是你在捕获时使用的,每次执行它都会给出匹配,然后是捕获。(仅当正则表达式不是全局的时,匹配才会以给出完整匹配后跟捕获的方式运行)。
Exec 的另一个用途是获取匹配项的索引或位置。当您的正则表达式有一个变量时,您可以使用.lastIndex
并获取匹配的位置。正则表达式对象具有.lastIndex
,而正则表达式对象就是您所做.exec
的。点匹配是在字符串上完成的,然后您将无法执行 regex object dot lastIndex
一个字符串,具有匹配函数,它被传递一个正则表达式。和一个正则表达式,具有 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 - 表示未找到)。
如果你想拉伸匹配,你可以在捕获时使用它,但当正则表达式是全局的时不能使用它,当你这样做时,数组的内容不是所有的匹配,而是完整的匹配,然后是捕获。
该.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()示例(存储的正则表达式 + 使用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"]