一:问题
项目中使用了一个JSON第三方库: GitHub - josdejong/jsoneditor: A web-based tool to view, edit, format, and validate JSON
当用户编辑JSON格式的数据,查找替换时:
用户的期望结果是:$$ 被替换为$$_text,但是实际结果是被替换为$_text:
二:原因
第三方库源码中,替换部分并没有针对特殊替换模式作出处理:
Search.prototype.replace = function (input, replacement) { var options = this.$options; var re = this.$assembleRegExp(options); if (options.$isMultiLine) return replacement; if (!re) return; var match = re.exec(input); if (!match || match[0].length != input.length) return null; replacement = input.replace(re, replacement); …… }
三:解决
提出pr针对此情况的replacement进行预处理:
{ …… replacement = input.replace(re, replacement.replace(/\$/g, "$$$$")); …… }
测试如下:
{ …… const test = "$$"; console.log(test.replace(test, "$$_text".replace(/\$/g, "$$$$"))); …… }
四:特殊替换模式
JavaScript的字符替换有一些特殊的规则,替换字符串可以包括以下特殊替换模式,其中只有当
pattern
参数是一个 正则是,$n
和$<Name>
才可用。如果pattern
是字符串,或者相应的捕获组在正则表达式中不存在,则该模式将被替换为一个字面量。如果该组存在但未匹配(因为它是一个分支的一部分),则将用空字符串替换它。针对$$之外的五种模式举例测试如下:
{ …… // $& var str1 = "ptest0229"; console.log(str1.replace('t', '$&T')); // $` var str2 = "ptest0229"; console.log(str2.replace('t', '$`T')); // $' var str3 = "ptest0229"; console.log(str3.replace('t', "$'T")); // $n var str4 = "p4"; var reg4 =/(^[a-z])(\d{1})/g; var res4 = str4.replace(reg4, "$1"); console.log(res4); // $<Name> var str = "p0"; var reg =/(?<NAME>(^[a-z]))(\d{1})/g; var res = str.replace(reg, "$<NAME>"); console.log(res); …… }
其中, $n中n设置为1,所以$1指的是正则表达式中第一组匹配的值:
$<Name>中Name指的是正则组的名字
结果如下: