Javascript RegExp和#x2019;s exec()函数和字符串’;s match()函数?

Javascript RegExp和#x2019;s exec()函数和字符串’;s match()函数?,javascript,regex,Javascript,Regex,如果我运行这个: /([^\/]+)+/g.exec('/a/b/c/d'); '/a/b/c/d'.match(/([^\/]+)+/g); 我明白了: ["a", "a"] 但如果我运行这个: /([^\/]+)+/g.exec('/a/b/c/d'); '/a/b/c/d'.match(/([^\/]+)+/g); 然后我得到了预期的结果: ["a", "b", "c", "d"] 有什么区别吗?exec与全局正则表达式意味着要在循环中使用,因为它仍然会检索所有匹配的子表达式。

如果我运行这个:

/([^\/]+)+/g.exec('/a/b/c/d');
'/a/b/c/d'.match(/([^\/]+)+/g);
我明白了:

["a", "a"]
但如果我运行这个:

/([^\/]+)+/g.exec('/a/b/c/d');
'/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
为您执行此操作,并丢弃捕获的组。

/regex/.exec()
仅返回找到的第一个匹配项,而
“String.match()
如果在regex中使用
g
标志,则返回所有匹配项


请看这里:,。

一张图片更好,你知道

re_once=/([a-z])([a-z])/
re_glob=/([a-z])([a-z])/g
st=“aAbBcC”
console.log(“匹配一次=“+st.match(re_once)+”匹配全局=“+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))
如果您的正则表达式是全局的,并且您正在捕获,那么您必须使用exec。Match不会返回您的所有捕获

匹配在仅匹配(而不是捕获)时非常有效。您运行它一次,它将给出一个包含所有匹配项的数组。(但如果正则表达式不是全局的,则match将显示匹配,然后显示捕获)

Exec是您在捕获时使用的,每次执行它时,它都会给出匹配,然后是捕获。(只有在正则表达式不是全局的情况下,match的行为方式是在捕获之后提供完全匹配)

Exec的另一个用途是获取匹配的索引或位置。当您的正则表达式有一个变量时,可以使用
.lastIndex
并获取匹配的位置。正则表达式对象具有
.lastIndex
,而正则表达式对象就是您在上执行的
.exec
。点匹配是在字符串上完成的,然后您将无法执行正则表达式对象点lastIndex

字符串,具有match函数,该函数传递一个正则表达式。一个正则表达式,具有exec函数,并被传递一个字符串

执行您多次运行的命令。比赛你跑一次

不捕获时使用match很好,捕获时可以使用功能更强大的exec,因为它有利于捕获,但如果捕获时确实使用match,请确保它在正则表达式不是全局时显示捕获,而在正则表达式是全局时不显示捕获

> "azb".match(/a(z)b/);
[ "azb", "z" ]

> "azb".match(/a(z)b/g);
[ "azb" ]
>
另一件事是,如果您使用exec,请注意,它是在regex上调用的,那么如果您为regex使用了变量,那么您就有了更多的能力

如果不将变量用于正则表达式,则无法获得匹配项,因此在使用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-表示未找到)

如果要拉伸匹配,可以在捕获时使用它,但不能在正则表达式为全局时使用,并且在执行此操作时,数组的内容不是所有匹配,而是捕获后的完全匹配。

函数
str.match(regexp)
将执行以下操作:

  • 如果存在匹配项,它将返回:
    • 如果在regexp中使用了
      g
      标志,它将返回所有子字符串(忽略捕获组)
    • 如果
      g
      标志在regexp中未使用:它将返回与
      regexp.exec(str)
  • 如果没有匹配项,则返回:
    • null
使用
g
标志的.match()示例:

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
不带
g
标志的.match()等同于.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

函数
regexp.exec(str)
将执行以下操作:

  • 如果存在匹配项,它将返回:
    • 如果在regexp中使用了
      g
      标志,则它将返回(每次调用时)
      [N\u MatchedStr,N\u Captured1,N\u Captured2,…]
      下一次的
      N
      匹配重要提示:如果regexp对象未存储在变量中(它需要是同一个对象),它将不会进入下一个匹配
    • 如果
      g
      标志在regexp中未使用:它将返回与具有
      g
      标志且第一次且仅一次被调用时相同的结果
  • 如果没有匹配项,则返回:
    • null
.exec()的示例(使用
g
标志存储的regexp+=它随每次调用而变化):

.exec()不随每次调用而更改时的示例:

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
}
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"]
有时regex.exec()比string.match()花费的时间要多得多

值得一提的是,如果string.match()和regex.exec()的结果相同(例如:不使用\g标志时), regex.exec()将取x2到x30之间的某个位置,然后是string.match():


因此,在这种情况下,仅当需要全局正则表达式(即执行多次)时,才应使用“new RegExp().exec()”方法。

使用
exec
循环以获得所有子选择。请注意,不需要第二个
+
,因为
match
将返回所有子表达式
.exec
每次只返回一个,因此它也不需要
+