JavaScript正则表达式- 用相同数量的另一个字符替换一系列字符

12

我正在尝试在JavaScript中将字符串的一部分替换为相同数量的虚拟字符,例如:'==Hello=='替换为'==~~~~~=='。

此问题已经有人用PerlPHP回答了,但是我无法在JavaScript中实现。我一直在尝试这个:

txt=txt.replace(/(==)([^=]+)(==)/g, "$1"+Array("$2".length + 1).join('~')+"$3");

模式匹配正常,但替换部分不正确 - 第二部分添加的是“~~”而非模式匹配的长度。将“$2”放在括号内不起作用。我该怎么做才能让它插入正确数量的字符?


正则表达式相关/重复问题:https://dev59.com/s2s05IYBdhLWcg3wR_23 - blahdiblah
4个回答

13

使用一个替换函数:

var txt = "==Hello==";
txt = txt.replace(/(==)([^=]+)(==)/g, function ($0, $1, $2, $3) {
    return $1 + (new Array($2.length + 1).join("~")) + $3;
});

alert(txt);
//-> "==~~~~~=="

3
"最初的回答" 的问题在于表达式。
txt.replace(/(==)([^=]+)(==)/g, "$1"+Array("$2".length + 1).join('~')+"$3") 

这是因为"$2".length会将$2作为字符串字面量,即长度为2的字符串"$2"。根据MDN文档

由于我们希望在最终进行替换之前进一步转换匹配结果,所以必须使用函数。

这样可以强制在变换之前进行匹配。

使用内联函数作为参数(和repeat)-- 这里的$1、$2、$3是局部变量:

(翻译中如有不妥之处,请多多指教)

txt.replace(/(==)([^=]+)(==)/g, (_,$1,$2,$3) => $1+'~'.repeat($2.length)+$3);

txt = '==Hello==';

//inline function
console.log(
  txt.replace(/(==)([^=]+)(==)/g, (_, g1, g2, g3) => g1 + '~'.repeat(g2.length) + g3)
);


非常整洁的答案,而且在我的情况下也有效。谢谢! - Yan King Yin

1

在进行$2替换之前,长度属性将被评估,因此replace()无法起作用。 Augustus建议的函数调用应该可以解决问题,另一种方法是使用match()而不是replace()。

使用没有/g的match()会返回一个匹配结果数组,可以像预期的那样连接。

txt="==Hello==";
mat=txt.match(/(==)([^=]+)(==)/);  // mat is now ["==Hello==","==","Hello","=="]
txt=mat[1]+Array(mat[2].length+1).join("~")+mat[3]; // txt is now "==~~~~~=="

你从中间表达式中排除了前导/尾随字符,但如果你想要更多的灵活性,你可以使用这个方法来处理由前导/尾随文字括起来的任何内容。

mat=txt.match(/(^==)(.+)(==$)/)

0

一个工作示例使用以下片段:

var processed = original.replace(/(==)([^=]+)(==)/g, function(all, before, gone, after){
    return before+Array(gone.length+1).join('~')+after;
});

你代码中的问题在于你总是测量"$2"的长度(始终是一个包含两个字符的字符串)。通过使用该函数,你可以测量匹配部分的长度。请参阅替换文档以获取更多示例。

你的代码有一个小错误,会返回比预期少一个字符。这是因为数组长度需要比字符串长度多1,才能使join()方法生成一个等长的替换字符串。 - Andy E

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接