【问题标题】:JavaScript regular expression iterator to extract groups用于提取组的 JavaScript 正则表达式迭代器
【发布时间】:2011-03-02 11:31:49
【问题描述】:

假设我们有以下文本:“1 a,2 b,3 c,4 d”和以下表达式:/\d (\w)/g

我们要做的是提取正则表达式所表示的a、b、c、d。

不幸的是 "1 a,2 b,3 c,4 d".match(/\d (\w)/g) 将产生一个数组: 1 a,2 b,3 c,4 d 和 RegExp.$1将仅包含上次匹配的组,即 RegExp.$1 == 'd'。

我如何迭代这个正则表达式,以便我也可以提取组...我正在寻找一种内存高效的解决方案,即某种迭代器对象

编辑: 它必须是通用的。我在这里只提供一个简单的例子。一种解决方案是遍历数组并为没有全局标志的每个项目重新应用正则表达式,但我发现这个解决方案有点愚蠢,尽管它似乎是唯一的方法。

【问题讨论】:

  • 接受您最近提出的问题。
  • 是否需要正则表达式?您也可以按空格和逗号分隔并以这种方式提取。
  • 是的,因为我只提供一个简单的例子......它比这更复杂。一种解决方案是为数组中的每个匹配项重新应用正则表达式,但这很愚蠢

标签: javascript regex node.js


【解决方案1】:
var myregexp = /\d (\w)/g;
var match = myregexp.exec(subject);
while (match != null) {
    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
    match = myregexp.exec(subject);
}

(无耻取自RegexBuddy

【讨论】:

  • 我不太明白。 match 只是一个包含所有元素的数组,如 1 a、2 b、3 c 等...除非重新应用正则表达式或有 API 来执行此操作,否则我们无法以这种方式提取捕获组...
  • @Pass - 当你使用 exex 时不是 - 匹配将包含整个匹配作为第一个元素,每个组作为其他元素,例如,['1 a', 'a']
  • match[0] 是整个匹配项(例如1 a); match[1] 是第一个捕获组 (a)。这会遍历字符串(参见 while 块的最后一行)。
【解决方案2】:

更短、更简单(尽管可能效率较低)的解决方案是使用String.prototype.replace。 replace 的独特之处在于它隐式地迭代所有匹配项并为每个匹配项执行一个函数。当然,您可以使用该函数来实际替换文本,但尽管函数名称并不是真正需要的:

"1 a,2 b,3 c,4 d".replace(/\d (\w)/g, function(complete_match, matched_letter) {
    console.log(matched_letter);
});

这会将abc,然后d 记录到控制台。 (它也会碰巧返回"undefined,undefined,undefined,undefined",但我们在这里不关心。)

更一般地说,替换is called with the following parameters的函数参数:

function(match, p1, p2, [...], offset, string)
  • match 是匹配的子字符串。
  • p1 等是比赛的捕获组,如果有的话。这些组按照它们对应的左括号的顺序排列(即最左边的第一个,外部的第一个)。如果组匹配多个子字符串(即在(.)+ 场景中),则仅捕获最后一个(最右边的)子字符串。
  • offset 是本次匹配的原始字符串中的索引
  • string 是调用 replace 的字符串。

手动迭代可能更有效,但这种方法并不慢,而且更短且(恕我直言)更易于阅读;我倾向于在手动循环中使用这种模式。

【讨论】:

    【解决方案3】:

    这会奏效:

    "1 a,2 b,3 c,4 d".match(/\w(?:,|$)/g).join(' '); // => "a, b, c, d"
    

    如果您需要迭代:

    var r = /\d (\w)/g,
        s = "1 a,2 b,3 c,4 d",
        m;
    
    while ( m = r.exec(s) ) {
        // `m` is your match, `m[1]` is the letter
    }
    

    【讨论】:

    • 感谢您的建议,但示例太具体了。我正在寻找通用解决方案,因为我的实际代码使用了更复杂的正则表达式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多