用JavaScript替换捕获组内容

时间:2015-05-07 14:36:04

标签: javascript regex

在我的JavaScript代码中,我有一个包含捕获组的正则表达式(由库用户配置)和一个与此正则表达式匹配的源字符串。正则表达式匹配整个字符串(即它的开头和结尾有^$个字符。)

一个愚蠢的例子:

var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";

我想重新组合源字符串,替换捕获组中的值并保持字符串的其余部分不变。请注意,虽然此示例的大部分“字符串的其余部分”位于其末尾,但它实际上可能位于其他任何位置。

例如:

var replacements = [ "ZX", "321" ];
var expectedString = "ZX-321_foo";

有没有办法在JavaScript中执行此操作?

注意:正则表达式由库用户通过旧API配置。我不能要求用户提供第二个正则表达式来解决这个问题。

2 个答案:

答案 0 :(得分:1)

在不改变正则表达式的情况下,我能想到的最好的是一个替换匹配的回调

sourceStr = sourceStr.replace(regex, function(match, $1, $2, offset, str) {
    return str.replace($1, replacements[0]).replace($2, replacements[1]);
});

这不是一个很好的解决方案,因为它会像

那样失败
var sourceStr = "ab_ab-123_foo";

因为它会替换第一个ab而不是匹配的等等。但是对于给定的示例和任何不重复匹配字符的字符串都适用



var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";

var replacements = [ "ZX", "321" ];

sourceStr = sourceStr.replace(regex, function(match, $1, $2, offset, str) {
    return str.replace($1, replacements[0]).replace($2, replacements[1]);
});

document.body.innerHTML = sourceStr;




答案 1 :(得分:0)

我认为这很接近。它满足了两个测试用例,但我不确定前导和尾随分组。

function replacer (regex, sourceStr, replacements) {

  // Make a new regex that adds groups to ungrouped items.

    var groupAll = "";
    var lastIndex = 0;
    var src = regex.source;
    var reGroup=/\(.*?\)/g;
    var match;
    while(match = reGroup.exec(src)){
        groupAll += "(" + src.substring(lastIndex, match.index) + ")";
        groupAll += match[0];
        lastIndex = match.index + match[0].length;
    }

    var reGroupAll = new RegExp(groupAll);

  // Replace the original groupings with the replacements
  // and append what was previously ungrouped.

    var rep = sourceStr.replace(reGroupAll, function(){

        // (match, $1, $2, ..., index, source)
      var len = arguments.length - 2;
      var ret = "";

      for (var i = 1,j=0; i < len; i+=2,j++) {
        ret += arguments[i];
        ret += replacements[j];
      }
      return ret;
    });

    return rep;
}


var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/;
var sourceStr = "ab-123_foo";
var replacements = [ "ZX", "321" ];
var expectedString = "ZX-321_foo";

var replaced = replacer(regex, sourceStr, replacements);
console.log(replaced);
console.log(replaced === expectedString);

regex = /^.*_([a-zA-Z]{2})-([0-9]{3})$/;
sourceStr = "ab_ab-123";
expectedString = "ab_ZX-321";

var replaced = replacer(regex, sourceStr, replacements);
console.log(replaced);
console.log(replaced === expectedString);

输出:

ZX-321_foo
true
ab_ZX-321
true