本文同步自我的个人博客:http://www.52cik.com/2015/11/06/replace-all.html

关于字符串替换问题,其实是个很简单的问题,但却也不那么简单,至少对于很多新手而言,全局替换一直是个坑。

简单而强大的正则

可能你觉得要替换全局,就改成正则,然后加个 g 全局匹配就好了,例如:

var str = "test-test-test";
str = "test-test-test".replace("test", "ok");
console.log(str);

改成正则:

var str = "test-test-test";
str = "test-test-test".replace(/test/g, "ok");
console.log(str);

确实非常简单,但是如果出现需要转义的字符呢?
当然也难不倒大家,但是对于新手而言,正则就是一座无形的大山,完全无法越过。

无奈的正则

例如表情标签的替换呢?难道全部改成正则?那也要会正则的人花不少体力才能搞定吧。
今天群里的朋友就遇到这么个问题,表情标签如下:

var faces = {"/::)": "weixiao","/::~": "pizui","/::B": "se","/::|": "fadai","/:8-)": "deyi","/::<":"liulei","/::$": "haixiu","/::'(": "daku","/::-|": "gangga"
};

当然我只是截取了部分,好像有好几十个,如果全部改成正则,需要不少体力呢。

循环替换

这种情况,我们需要正常的字符串替换,例如结合 while + indexOf 实现。

var faces = {"/::)": "weixiao","/::~": "pizui","/::B": "se","/::|": "fadai","/:8-)": "deyi","/::<":"liulei","/::$": "haixiu","/::'(": "daku","/::-|": "gangga"
};var str = "/::)-/::B-/::)-/:8-)-/:8-)";for (var k in faces) {while(str.indexOf(k) > -1) {str = str.replace(k, faces[k]);}
}console.log(str);

这样,基本功能实现,不过这是有问题的,如果有一个键值相同的,就会死循环例如:

var faces = {"/::)": "weixiao","/:hehe": "/:hehe"
};var str = "/::)-/::B-/:hehe-/:8-)-/:8-)";for (var k in faces) {while(str.indexOf(k) > -1) {str = str.replace(k, faces[k]);}
}console.log(str);

这样,就呵呵了,当然不一定会有这样的情况,但也不能肯定一定没有这样的情况。

改进循环

我们需要用到 indexOf 的第二个参数来规避这种情况,改进后的代码如下:

var faces = {"/::)": "weixiao","/:hehe": "/:hehe"
};var str = "/::)-/::B-/:hehe-/:8-)-/:8-)";for (var k in faces) {var p = -1; // 字符出现位置var s = 0; // 下一次起始位置while((p = str.indexOf(k, s)) > -1) {s = p + faces[k].length; // 位置 + 值的长度str = str.replace(k, faces[k]);}
}console.log(str);

好了,现在这样就没问题了,也不用担心死循环问题,而且替换大段文字的时候,性能比正则要好。 经过测试,确实正则快。
在大段正则匹配的时候,回溯会导致匹配性能问题,所以才一直认为正则慢,而这种情况的正则,不需要回溯,性能自然也极佳。

为了方便新手朋友使用,下面写个函数吧。

/*** 字符串替换* @param  {string} str    要被替换的字符串* @param  {string} substr 要替换的字符串* @param  {string} newstr 用于替换的字符串* @return {string}        替换后的新字符串*/
function replace(str, substr, newstr) {var p = -1; // 字符出现位置var s = 0; // 下一次起始位置while((p = str.indexOf(substr, s)) > -1) {s = p + newstr.length; // 位置 + 值的长度str = str.replace(substr, newstr);}return str;
}console.log( replace("ssssss", "ss", "s") ); // sss

总结

我发现,我也只能写写这些小东西,唉。。

后记

在 4楼 Antineutrino 的测试中得知,正则方法比 while + indexOf 性能更佳。
之前一直认为正则就是慢的代名词,所以直接忽略了正则方法,现在又重新认识了正则,正则果然犀利。

抽空写了个正则版本的,把元字符种的几个符号转义下,就可以生成正则了。
网上那些正则版本中没有转义直接 new RegExp 的会导致各种bug,所以要处理下元字符的那些符号。

/*** 字符串替换* @param  {string} str    要被替换的字符串* @param  {string} substr 要替换的字符串* @param  {string} newstr 用于替换的字符串* @return {string}        替换后的新字符串*/
function replace(str, substr, newstr) {substr = substr.replace(/[.\\[\]{}()|^$?*+]/g, "\\$&"); // 转义字符串中的元字符var re = new RegExp(substr, "g"); // 生成正则return str.replace(re, newstr);
}console.log( replace("ssssss", "ss", "s") ); // sss

转载于:https://www.cnblogs.com/52cik/p/replace-all.html

replace 替换全部的正确姿势相关推荐

  1. word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...

    Hello,最近正值着手写毕业论文的初期,趁着这个时间点,我做了一个简易的,简单的,0基础的Word论文排版教学,帮助你在撰写论文的时候不再花费大量的时间浪费在调整格式里. 初次做视频,难免有错误,欢 ...

  2. 技术人看《长安十二时辰》的正确姿势是?

    阿里妹导读:从"叉手礼"."水盆羊汤"."酒晕妆"这些唐朝人的生活细节,到精美的坊间造型.充满意境的诗词歌赋,<长安十二时辰>不 ...

  3. 安卓源码AOSP下载使用的正确姿势

    安卓源码AOSP下载使用的正确姿势 从同步源码到编译完成,整个过程应至少准备200G空间. 编译时需要的内存数与编译线程数相关,博主实测比较极限的配置是4核8G,超过这个范围将触发swap交换导致编译 ...

  4. 聚焦东风汽车,解锁企业上云的正确姿势

    近年来,企业上云已经逐渐成为一种趋势,这不仅仅是企业业务发展的自身需求,也是国家政策层面的要求,早在2017年年底,信息化和软件服务业司司长谢少锋在介绍<深化"互联网+先进制造业&qu ...

  5. 论 做 AI 芯片的正确姿势

    https://xie.infoq.cn/article/d5ab8bea53fa8a08406fabf9d 论做 AI 芯片的正确姿势 作者:flow 2020-08-10 本文字数:14908 字 ...

  6. 有一说一!这才是RabbitMQ实现分布式事务的正确姿势(项目实战)

    分布式事务 随着互联网快速发展,微服务,SOA 等服务架构模式正在被大规模的使用,现在分布式系统一般由多个独立的子系统组成,多个子系统通过网络通信互相协作配合完成各个功能. 有很多用例会跨多个子系统才 ...

  7. 【214情人节】低调奢华有内涵的python程序猿撒狗粮的正确姿势(附源码)

    目录 一. 效果演示 1. 原图-效果图对比 2. 看出两张图片的区别了吗? 二. 代码架构 三. 功能实现 3.1 图片处理 3.2 html 使用form表单,真心话和图片文件的布局 3.3 js ...

  8. 使用java正则表达式的正确姿势

    使用java正则表达式的正确姿势 文章目录 使用java正则表达式的正确姿势 一.用途 二.. * + ? 表示什么意思? 三.[]表示什么意思?(控制范围) 四.常用的"\字母" ...

  9. 正确姿势开发vue后台管理系统

    项目地址 vue-admin-webapp 欢迎star,fork 前言 相信许多人和我一样刚接触 vue 时看文档都很枯燥,看完 vue,还有 vueRouter .vuex .vue-cli.es ...

最新文章

  1. mysql-事物实现原理
  2. android log时间,android – Logcat的日志时间戳不按顺序排列
  3. Delphi的内存管理及内存泄露问题
  4. 利用Log Explorer将你已经delete,truncate,drop过的数据进行恢复
  5. 计算机ftp怎么登陆新用户,多用户登录ftp
  6. 数据科学 IPython 笔记本 7.15 高性能 Pandas
  7. 利用scp在windows和linux之间进行文件和文件夹的数据拷贝
  8. java sql 写入万条数据_如何快速向数据库插1000万数据?4种方法对比,它简单却速度最快
  9. HDU4628+状态压缩DP
  10. 2021年中国传送控制器市场趋势报告、技术动态创新及2027年市场预测
  11. deinstall oracle 11g on linux
  12. [转载] Python中的memoryview
  13. Manecher算法
  14. 计算机cmd卸载软件,一招让你学会,在win10命令提示符上卸载程序
  15. 关于防范ONION勒索软件病毒攻击的解决办法
  16. 2021年剑桥高考成绩查询,2021年剑桥英语成绩查询指南
  17. UE4数据库 Mysql
  18. app端-留存分析-周留存率报表开发
  19. JPG/JEPG在十六进制文件格式
  20. 毕业设计房屋出租研究现状

热门文章

  1. 「Unity」UGUI的Text实现首行缩进的办法
  2. 前端-html、css
  3. prefuse学习(一)用非数据库连接和xml的方式读入数据
  4. css:学习CSS了解单位em和px的区别
  5. J2ME开发环境配置(MyEclipse插件+WTK+jdk)
  6. mysql jdbc链接配置文件_Java JDBC使用配置文件连接数据库
  7. AUTOSAR从入门到精通100讲(四)-CAN总线数据帧分类及格式详解
  8. java chsftp.get 追加_Java SFTP上传使用JSch,但如何覆盖当前文件?
  9. Java宣言的时候,Java基础恶补——宣言及访问控制
  10. 一文带你了解腾讯位置服务的开发与接入