Javascript - 正则表达式访问多次出现

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7280586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:36:49  来源:igfitidea点击:

Javascript - Regex access multiple occurrences

javascriptregex

提问by Pierre de LESPINAY

I have this text

我有这个文字

txt = "Local residents o1__have called g__in o22__with reports...";

in which I need to get the list of numbers between each oand __

其中我需要获取每个o和之间的数字列表__

If I do

如果我做

txt.match(/o([0-9]+)__/g);

I will get

我会得到

["o1__", "o22__"]

But I'd like to have

但我想拥有

["1", "22"]

How can I do that ?

我怎样才能做到这一点 ?

回答by soldier.moth

See this question:

看到这个问题

txt = "Local residents o1__have called g__in o22__with reports...";
var regex = /o([0-9]+)__/g
var matches = [];
var match = regex.exec(txt);
while (match != null) {
    matches.push(match[1]);
    match = regex.exec(txt);
}
alert(matches);

回答by jfriend00

You need to use .exec()on a regular expression object and call it repeatedly with the g flag to get successive matches like this:

您需要.exec()在正则表达式对象上使用并使用 g 标志重复调用它以获得连续匹配,如下所示:

var txt = "Local residents o1__have called g__in o22__with reports...";
var re = /o([0-9]+)__/g;
var matches;
while ((matches = re.exec(txt)) != null) {
    alert(matches[1]);
}

The state from the previous match is stored in the regular expression object as the lastIndexand that's what the next match uses as a starting point.

前一个匹配的状态作为 存储在正则表达式对象中lastIndex,这就是下一个匹配用作起点的状态。

You can see it work here: http://jsfiddle.net/jfriend00/UtF6J/

你可以在这里看到它的工作:http: //jsfiddle.net/jfriend00/UtF6J/

Using the regexp this way is described here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec.

此处描述了以这种方式使用正则表达式:https: //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec

回答by CaNNaDaRk

/o([0-9]+?)__/g

This should work. Click hereand search for "lazy star".

这应该有效。单击此处并搜索“懒惰之星”。

var rx = new RegExp( /o([0-9]+?)__/g );
var txt = "Local residents o1__have called g__in o22__with reports...";
var mtc = [];
while( (match = rx.exec( txt )) != null ) {
        alert( match[1] );
        mtc.push(match[1]);
}

Jek-fdrv pointed out in the comments, that if you call rx.test just before the while loop some results are skipped. That's because RegExp object contains a lastIndex field that keeps track of last match's index in the string. When lastIndex changes then RegExp keeps matching by starting from it's lastIndex value, therefore a part of the string is skipped. A little example may help:

Jek-fdrv 在评论中指出,如果您在 while 循环之前调用 rx.test,则会跳过某些结果。这是因为 RegExp 对象包含一个 lastIndex 字段,用于跟踪字符串中最后一个匹配项的索引。当 lastIndex 更改时,RegExp 会从它的 lastIndex 值开始保持匹配,因此会跳过一部分字符串。一个小例子可能会有所帮助:

var rx = new RegExp( /o([0-9]+?)__/g );
var txt = "Local residents o1__have called g__in o22__with reports...";
var mtc = [];
console.log(rx.test(txt), rx.lastIndex); //outputs "true 20"
console.log(rx.test(txt), rx.lastIndex); //outputs "true 43"
console.log(rx.test(txt), rx.lastIndex); //outputs "false 0" !!!
rx.lastIndex = 0; //manually reset lastIndex field works in Chrome
//now everything works fine
while( (match = rx.exec( txt )) != null ) {
        console.log( match[1] );
        mtc.push(match[1]);
}