【问题标题】:Javascript - Regex access multiple occurrences [duplicate]Javascript - 正则表达式访问多次出现[重复]
【发布时间】:2011-11-08 23:36:36
【问题描述】:

我有这段文字

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

我需要在其中获取每个 o__ 之间的数字列表

如果我这样做

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

我会得到

["o1__", "o22__"]

但我想拥有

["1", "22"]

我该怎么做?

【问题讨论】:

标签: javascript regex


【解决方案1】:

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);

【讨论】:

  • 不知道选哪一个,你的是第一个,但@friend00更详细:)
  • 好吧,让我们验证你的,你需要比 @jfriend00 更多的声誉 :)
  • 导致无限循环
【解决方案2】:

您需要在正则表达式对象上使用.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]);
}

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

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

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

【讨论】:

  • 我不知道选哪个更详细,但@Soldier.moth 是第一个:)
  • 可能有几个错别字,但 Soldier 的代码不起作用,因为它只调用一次 regex.exec()(作为循环的一部分,它必须被多次调用),它会进入如果它匹配任何内容,则无限循环,因为一旦 while 循环开始,match 的值就永远不会改变。
  • 哎呀!绝对错字,已修复。
  • 如果我调用验证此代码 re.test(txt) 然后尝试 do while,它会在第二场比赛中出现,我们输掉了第一场比赛。
  • @Jek-fdrv - 是的,如果你在你的正则表达式上使用g 选项,那么.test().exec() 每次调用它们时都会在目标字符串中向前推进一个匹配.该状态存储在正则表达式对象本身中。如果需要,您可以通过将正则表达式上的 .lastIndex 属性设置回 0 来重置该状态。
【解决方案3】:
/o([0-9]+?)__/g

这应该可以。 Click here 并搜索“懒星”。

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 在 cmets 中指出,如果您在 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]);
}

【讨论】:

  • 给我同样的结果。懒惰的东西是用 javascript 实现的吗?
  • 是的,他们是。我编辑并添加了一些代码,在本地测试并为我工作。显示两个带有“1”和“22”的警报
  • 现在它也填充了 mtc 数组。
  • 如果我调用验证此代码 rx.test(txt) 然后尝试 do while,它会在第二场比赛中出现,我们输掉了第一场比赛。
  • 没错,每次调用测试方法时,RegExp对象的lastIndex成员都会增加到下一个匹配位置,如果你下次调用匹配时不重置它(通过将其设置为0)或测试字符串仅从 lastIndex 值进行分析。尝试设置“rx.lastIndex = 0;”就在您要求测试然后再次调用匹配之后。这适用于 Chrome。我将编辑答案添加一个小例子。
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 2015-07-24
  • 2015-11-18
  • 2017-05-25
  • 2013-09-29
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
相关资源
最近更新 更多