关于字符串替换问题,其实是个很简单的问题,但却也不那么简单,至少对于很多新手而言,全局替换一直是个坑。
简单而强大的正则
可能你觉得要替换全局,就改成正则,然后加个 g 全局匹配就好了,例如:
1 | var str = "test-test-test"; |
改成正则:
1 | var str = "test-test-test"; |
确实非常简单,但是如果出现需要转义的字符呢?
当然也难不倒大家,但是对于新手而言,正则就是一座无形的大山,完全无法越过。
无奈的正则
例如表情标签的替换呢?难道全部改成正则?那也要会正则的人花不少体力才能搞定吧。
今天群里的朋友就遇到这么个问题,表情标签如下:
1 | var faces = { |
当然我只是截取了部分,好像有好几十个,如果全部改成正则,需要不少体力呢。
循环替换
这种情况,我们需要正常的字符串替换,例如结合 while + indexOf 实现。
1 | var faces = { |
这样,基本功能实现,不过这是有问题的,如果有一个键值相同的,就会死循环例如:
1 | var faces = { |
这样,就呵呵了,当然不一定会有这样的情况,但也不能肯定一定没有这样的情况。
改进循环
我们需要用到 indexOf 的第二个参数来规避这种情况,改进后的代码如下:
1 | var faces = { |
好了,现在这样就没问题了,也不用担心死循环问题,而且替换大段文字的时候,性能比正则要好。 经过测试,确实正则快。
在大段正则匹配的时候,回溯会导致匹配性能问题,所以才一直认为正则慢,而这种情况的正则,不需要回溯,性能自然也极佳。
为了方便新手朋友使用,下面写个函数吧。
1 | /** |
总结
我发现,我也只能写写这些小东西,唉。。
后记
在 4楼 Antineutrino 的测试中得知,正则方法比 while + indexOf 性能更佳。
之前一直认为正则就是慢的代名词,所以直接忽略了正则方法,现在又重新认识了正则,正则果然犀利。
抽空写了个正则版本的,把元字符种的几个符号转义下,就可以生成正则了。
网上那些正则版本中没有转义直接 new RegExp 的会导致各种bug,所以要处理下元字符的那些符号。
1 | /** |