Java教程

JavaScript正则表达式replace的一个坑

本文主要是介绍JavaScript正则表达式replace的一个坑,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题图来自:https://wallhaven.cc/w/md353k

经常听大家说JavaScript是魔法语言,咱却没有什么深刻体会。直到这回踩到这个坑,我终于醒悟了,JavaScript果然来自霍格沃茨!

trymagic_smaller-2021-11-06

0x00 踩到坑

昨天咱经过一番考虑后决定将 Python正则表达式细节小记 这篇笔记发到个人博客上。选好文章音乐,复制markdown内容...发布!

按照惯例我检查了一下发布后的文章内容,然后就见到了一个奇怪的现象:

issuehappens-2021-11-06

文章内容到一半的时候全被替换成 模板里的HTML 了...

之前调试博客的时候从没遇到过这个问题,我一时就有点摸不着头脑( >﹏<。),但没关系,比对一下原文档就应该知道问题在哪了:

comparison-2021-11-06

很明显能发现是从$开始被替换了,我心里咯噔一下:怕不是和正则表达式有关!不过在排查正则表达式之前我去改了一下博客后台部分的代码:

modifiedcode-2021-11-06

结果问题仍然存在,我接着还拿着这样的内容片段进行复现,但没能成功($并没有被替换成其他内容):

test$

 $ 
test$

0x01 坑在哪

到最后,我还是怀疑回了正则表达式,但想来想去还是摸不着头脑,正则表达式和用作替换的字符串有什么关系,$不是用在正则表达式里的吗?而且为什么刻意用$去复现又不行呢?

baldscratch-2021-11-07

实在不行只能去求助一下某搜索引擎了:

googlesearch-2021-11-07

不查不知道,一查吓一跳,看到有老哥提到了replace函数接收的字符串不仅仅是字符串,我赶紧去MDN查了一下:

syntaxofreplace-2021-11-07

原来用作替换的字符串内能包括一些特殊的变量名!

变量名 代表的值
$$ 插入一个 "$"。
$& 插入匹配的子串。
$` 插入当前匹配的子串左边的内容。
$' 插入当前匹配的子串右边的内容。
$n 假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始。如果不存在第 n个分组,那么将会把匹配到到内容替换为字面量。比如不存在第3个分组,就会用“$3”替换匹配到的内容。
$ 这里Name 是一个分组名称。如果在正则表达式中并不存在分组(或者没有匹配),这个变量将被处理为空字符串。只有在支持命名分组捕获的浏览器中才能使用。

表格原地址: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/replace#使用字符串作为参数

现在再回去看文章markdown内容,有一部分我是这样写的:

到了这里,我发现老师说的在```[]```中**被当作普通字符**的元字符只是一部分罢了,主要是 ```*```,```?```,```+```,```{}```,```()```,```$``` 这些元字符。

毫无疑问其中的$\`就被替换为了匹配字串左边的内容,也就是模板的前面一部分,才导致文章被处理成这样。

可以说真的非常魔法了,万万没想到JavaScript竟然在待替换字符串这里内置了一些$变量名的用法。要是我没有想着把这篇小记发到个人博客上,说不定还得要好一阵子才能发现这个问题。

0x02 解决方法

解决方法其实很简单,str.replace(regexp|substr, newSubStr|function)的第二个参数是可以接受一个函数的,而这个函数的 返回值 就被直接用作匹配项替换了,而不是先寻找一遍$变量名。

比如我原来是这样写的:

str.replace(new RegExp('\\{\\[' + from + '\\]\\}','gi'), to);

那么我用箭头函数改写一下就行了:

str.replace(new RegExp('\\{\\[' + from + '\\]\\}','gi'), ()=>to);

其实就相当于:

str.replace(new RegExp('\\{\\[' + from + '\\]\\}','gi'), function(){
    return to;
});

关于这个函数传入的参数可以看MDN文档这里的 指定一个函数作为参数

usefuncasarg-2021-11-07

0x03 教训

以后写JavaScript代码的时候还是不能掉以轻心了,说不定在哪个角落还有我不太清楚的魔法。遇到不会或者不清楚的一定要多查文档,不然一旦写进项目里可能就会成为一个遗留的潜在问题。(ノへ ̄、)

这篇关于JavaScript正则表达式replace的一个坑的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!