在我的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配置。我不能要求用户提供第二个正则表达式来解决这个问题。
答案 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