replace 替换全部的正确姿势

本文同步自我的个人博客: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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA - 单例设计模式

JAVA - 单例设计模式 一. 简介二. 单例模式的原则三. 单例模式的实现1.1 饿汉式1.1.1 静态变量初始化方式1.1.2 静态代码块初始化方式1.1.3 枚举方式 1.2 懒汉式1.2.1 懒加载初始化方法 (线程不安全)1.2.2 懒加载初始化方法 (线程安全&#x…

http请求报文

关于urlURL 是大型标识符 URI(统一资源标识)的一部分。这个超集是建立在已有的命名惯例基础上的。一个 URL 是一个简单的 URI,使用已存在的协议或规划(也就是 http,ftp 等)作为地址的一部分。为了进一步描绘这些,我们将会Edit By Vheavens Edit By Vheavens 引入 non-URL 的 UR…

operanbsp;内容拦截

结束我大opera的一个好用功能 内容拦截 博客的主要很清爽,也可以自定义.非常好, 但打开博文,左边的特别的精彩图文,瞄到就不高兴.好的 开始 右键-内容拦截 shift 点那个精彩xx,最右上角,广告, 然后点完成.ok了 貌似我大遨游的广告拦截更好用 转载于:https://www.cnblogs.com/wa…

Solr-5.3.1安装配置

Solr-5.3.1安装配置官方网站:http://lucene.apache.org/solr/http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htmlhttp://lucene.apache.org/solr/quickstart.html环境:CentOS6 x64Solr-5.3.1从Solr5.0开始,Solr不再发布为在任何…

EF for Firebird

今天用了Firebird,记录下怎么用,不然下次给忘记了 1.官网下载包 1.DDEXProvider-3.0.1.0.msi 2.FirebirdSql.Data.FirebirdClient-4.6.2.0.msi 备注: 1.发现DDEXProvider 与 FirebirdSql.Data.FirebirdClient安装有先后顺序 1.如果中间出现了…

php几个函数

1. dirname (PHP 3, PHP 4, PHP 5) dirname -- 返回路径中的目录部分说明 string dirname ( string path )给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名。 在 Windows 中,斜线(/)和反斜线&#xf…

Struts2 自定义拦截器(easy example)

要自定义拦截器需要实现com.opensymphony.xwork2.interceptor.Interceptor接口: 新建一个MyInterceptpackage com.action;import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor;public class MyInterceptor i…

img标签在div里上下居中

方法一&#xff1a;图片尺寸未知&#xff0c;IE8-不支持 CSS部分&#xff1a; <style> .content{width:500px;height:500px;border:1px solid black;position:relative; } </style>DOM部分&#xff1a; <div class"content"> <img src"htt…

(接口)银联证书上传被修改的问题和读取证书的绝对路径问题

最近在做对接银联的支付接口。相对于支付宝、微信支付&#xff0c;银联支付接口应该是做的最完美的了。银联支付平台提供了足够详细的接口文档&#xff0c;接口demo&#xff0c;常见问题解决方案。 更人性化的是&#xff0c;个人可以免费注册一个商家账号&#xff0c;提供给你免…

控制器对视图声明周期的控制

init&#xff0d;初始化程序 viewDidLoad&#xff0d;加载视图 viewWillAppear&#xff0d;UIViewController对象的视图即将加入窗口时调用&#xff1b; viewDidApper&#xff0d;UIViewController对象的视图已经加入到窗口时调用&#xff1b; viewWillDisappear&#xff0d;UI…

MST:Bad Cowtractors(POJ 2377)

坏的牛圈建筑 题目大意&#xff1a;就是现在农夫又要牛修建牛栏了&#xff0c;但是农夫想不给钱&#xff0c;于是牛就想设计一个最大的花费的牛圈给他&#xff0c;牛圈的修理费用主要是用在连接牛圈上 这一题很简单了&#xff0c;就是找最大生成树&#xff0c;把Kruskal算法改一…

有关进程的一些基本概念

对进程的初步描述 一.和进程有关的一些概念 ①一个进程就是一个正在执行程序的实例&#xff0c;包括程序计数器&#xff0c;寄存器和变量的当前值。 从概念上说&#xff0c;每个进程拥有它自己的虚拟CPU&#xff0c;当然真实的CPU在各个进程之间来回切换。 ②在某一瞬间&…

第4章 maven依赖特性

第4章 maven依赖特性 本章详细介绍maven的依赖特性和依赖范围&#xff0c;如何排除依赖。 4.1 什么是依赖传递 举个例子 在非maven项目中&#xff0c;你需要使用spring功能&#xff0c;你会想到导入spring的jar包&#xff0c;那么&#xff0c;srping又需要其他依赖jar包支持&a…

lintcode :Integer to Roman 整数转罗马数字

题目 整数转罗马数字 给定一个整数&#xff0c;将其转换成罗马数字。 返回的结果要求在1-3999的范围内。 样例 4 -> IV 12 -> XII 21 -> XXI 99 -> XCIX 更多案例&#xff0c;请戳 http://literacy.kent.edu/Minigrants/Cinci/romanchart.htm 说明 什么是 罗马数字…

Win32ASm学习[1]:RadASm下测试Debug

okay 正文开始下面的代码如果不能编译 请把你的RadAsm下的Masm32这个文件夹复制到任意一个磁盘的根目录下&#xff0c;在进行编译就可以了 或者安装Masm32 SDK到任意磁盘根目录下 .386.model flat,stdcalloption casemap:none;>>>>>>>>>>&g…

关于javascript闭包

1.闭包的概念 闭包就是能够读取其他函数内部变量的函数。 由于在Javascript语言中&#xff0c;只有函数内部的子函数才能读取局部变量&#xff0c;因此可以把闭包简单理解成“定义在一个函数内部的函数”。 所以&#xff0c;在本质上&#xff0c;闭包就是将函数内部和函数外部连…

Win32ASM学习[2]:运算符

算术运算符 名称 优先级 () 圆括号 1 ,- 正、负 2 *,/ 乘、除 3 MOD 取模 3 ,- 加、减 4 ------------------------------------------------------------------------------------------------------------------------------------------ .386 .mo…

正式入住了

从13年开始从事iOS开发工作,就准备写一些东西,记录这一路学习工作之旅,但是总是想着坚持不下来,也就慢慢的放弃了,开始用一些记笔记的软件,印象笔记用过,个人体验比较差,后来又用了OneNote,这个APP还是比较舒服,但是由于公司的老版mac-pro,无法使用,也就突然想起了,也是时候重出…

VRRP协议具体解释

转帖&#xff1a;http://blog.chinaunix.net/space.php?uid11654074&doblog&id2857384 Contents Page 文件夹 入木三分学网络…