替换JavaScript中的捕获组内容
在我的JavaScript代码中,我有一个带有捕获组(由库用户配置)的正则表达式和一个与该正则表达式匹配的源字符串。正则表达式匹配整个字符串(即,它的开头和结尾有替换JavaScript中的捕获组内容,javascript,regex,Javascript,Regex,在我的JavaScript代码中,我有一个带有捕获组(由库用户配置)的正则表达式和一个与该正则表达式匹配的源字符串。正则表达式匹配整个字符串(即,它的开头和结尾有^和$字符) 一个愚蠢的例子: var regex = /^([a-zA-Z]{2})-([0-9]{3})_.*$/; var sourceStr = "ab-123_foo"; 我想重新组合源字符串,替换捕获组中的值,并保持字符串的其余部分完好无损。请注意,虽然这个示例的末尾有大部分“字符串的其余部分”,但实际上它可能在其他任何地
^
和$
字符)
一个愚蠢的例子:
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进行配置。我不能要求用户提供第二个正则表达式来解决这个问题。在不更改正则表达式的情况下,我能想到的最好方法是使用回调来替换匹配项
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替换=[“ZX”,“321”];
sourceStr=sourceStr.replace(正则表达式,函数(匹配,$1,$2,偏移量,str){
返回str.replace($1,replacements[0])。replace($2,replacements[1]);
});
document.body.innerHTML=sourceStr代码>我认为这很接近。它满足两个测试用例,但我不确定前导和尾随分组
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);
但是你能要求你的用户修改正则表达式吗?如果是这样的话,您可以用另一对括号括住字符串的其余部分并免费获得它。我可以自己编程修改正则表达式以达到这一效果,我认为似乎可以通过编程方式将/^([a-zA-Z]{2})-(0-9]{3})$/
转换为/^([a-zA-Z]{2})([0-9]{3})([u.*$/
),不知道?我不太清楚你是如何做到的,但我想这涉及到将正则表达式转换成字符串,对该字符串进行替换,并将其传递给正则表达式构造函数,虽然这是可能的,但我不确定这是一个非常好的主意?为什么这是一个坏主意?我不知道,对我来说,获取正则表达式的字符串值并进行替换,然后将其传递回RegExp构造函数似乎有点不确定。正如我所说的,这是可能的,而且它很可能会工作,这是重要的一部分,我个人只是不太喜欢它,我不知道它的结构,RegExp是由库用户配置的。@AlexanderGladysh我为未知的正则表达式调整了答案。比如说,对于stringab-123
和regex/^.*.\uz([a-zA-Z]{2})-([0-9]{3})$/
?@AlexanderGladysh ab_ab-123测试失败,因此我更改了替换程序以满足该测试用例。
ZX-321_foo
true
ab_ZX-321
true