原生js实现replace方法
今天看到有人提问js的replace方法怎么实现的,自己就试了试
js手册里的String对象的介绍replace大概是这样:
string.replace(regexp, replacement)
第一个参数:(regexp)
声明了要替换的模式的RegExp对象。如果该参数是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换成RegExp对象。
第二个参数(replacement)
一个字符串,声明的是替换文本或生成替换文本的函数。详见描述部分。
返回值
一个新字符串,是用replacemenc替换了与regexp的第一次匹配或所有匹配之后得到的。
我就试着实现了下一开始思路没考虑到正则,有很多问题,经过修改过的思路:
使用了正则的exec(),用split将匹配到的字符串作为参数把原字符串分割成若干数组,然后将字符串和替换的内容连接join起来就实现了
exec()将检索字符串string,从中得到与正则表达式regexp相匹配的文本。如果exec()找到了匹配的文本,它就会返回一个结果数组。否则,返回null。
匹配到的第一个数组[0]:匹配的文本,
第2个元素是与regexp的第二个子表达式相匹配的文本,以此类推。通常,数组的length属性声明的是数组中的元素个数。除了数组元素和length属性之外,exec()还返回两个属性。index属性声明的是匹配文本的第一个字符的位置。input属性指的就是string。在调用非全局RegExp对象的exec()方法时,返回的数组与调用方法String.match()返回的方法相同。
String.prototype.replaces=function(reg,str){
var arr = [];
var newStr= this;
var i= '';
//循环到 匹配不到替换的字符串为止
while(reg.exec(newStr)!='null') {
/**使用try,catch是因为在循环到匹配到所有!=null下次循
环reg.exec(newStr)[0]会报错,循环完到报错时直接return结果**/
try{
arr = newStr.split(reg.exec(newStr)[0]);
newStr = arr.join(str);
//如果该正则式子不是全局正则(/g)不作循环直接修改一次返回
if(!reg.global){
return newStr;
}
}catch(e){
return newStr;
}
}
}
console.log("我是AbCd啊abcd啊abcd".replaces(/abcd/gi,'lipengpeng'))
----------------------------------------------------
经过测试,上面代码存在的问题如下:
当正则表达式是全局时(/g)时,且只匹配到一个,会直接返回原字符串,
在循环reg.exec(newStr)时,每次结果都不一样,这里暂时不清楚原因
修改后的:
String.prototype.replaces=function(reg,str){
var arr = [];
var newStr= this;
var i= '';
var d;
//为了防止reg.exec()每次结果不一样,直接赋给一个变量
//这里注意给d=reg.exec()加括号, “=”的优先级低
while((d = reg.exec(newStr))!=null) {
try{
arr = newStr.split(d[0]);
newStr = arr.join(str);
if(reg.global){
return newStr;
}else{
break;
}
}catch(e){
console.log(e)
}
}
}
---------------------------------分割线-------------------------------------
以上代码继续测试后,发现如果正则匹配到不区分大小写(/i)且不开启全局匹配,结果会全局替换。添加非全局代码,不用管大小写在全局或非全局(正则已经处理过),最终代码:
String.prototype.replaces = function(reg, str) {
var arr = [];
var newStr = this;
var i = '';
var d;
while((d = reg.exec(newStr)) != null) {
//debugger
try {
//console.log(d)
if(reg.global) {
arr = newStr.split(d[0]);
newStr = arr.join(str);
} else {
var index = d['index'];
var lastindex = (+index) + (+d[0].length);
var preStr = newStr.slice(0, index);
var nextStr = newStr.slice(lastindex);
newStr = preStr + str + nextStr;
break;
}
} catch(e) {
console.log(e)
}
}
return newStr
}
var s = "我是A,c,a,cc,c,c,cc,a".replaces(/a/ig, 'b')
console.log(s)原生js实现replace方法的更多相关文章
- 原生Js 两种方法实现页面关键字高亮显示
原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...
- 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别
一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...
- 原生JS中apply()方法的一个值得注意的用法
今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...
- js的replace方法
今天在项目中发现,js的replace方法,其实只是替换第一个匹配的字符: 比如 backstreetboy.replace('b','B') 得到的结果是Backstreetboy,只是替换了第一个 ...
- 原生JS添加节点方法与jQuery添加节点方法的比较及总结
一.首先构建一个简单布局,来供下边讲解使用 1.HTML部分代码: <div id="div1">div1</div> <div id="d ...
- 原生JS实现new方法、new一个对象发生的四部、new里面常用的优先级
一.js中new一个对象的过程 首先了解new做了什么,使用new关键字调用函数(new ClassA(…))的具体步骤: 1.创建一个新对象: var obj = {}; 2.设置新对象的const ...
- 【CSS进阶】原生JS getComputedStyle等方法解析
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 扩展原生js的一些方法
扩展原生js的Array类 Array.prototype.add = function(item){ this.push(item); } Array.prototype.addRange = fu ...
- 原生js的各种方法
原生js操作dom元素 var link = document.createElement( "link" );link.type = "image/x-icon&quo ...
随机推荐
- CentOS7部署yum环境及虚拟机快照克隆
CentOS部署IP地址 第一种:nmtui 方向键.tab.空格.回车第二种:修改网卡配置文件 /etc/sysconfig/network-sripts/ifcfg- ...
- ORs-3-OR Gene Family Phylogeny
OR Gene Family Phylogeny 1.之前关于ORs基因构建系统生发树的研究中的不足:bootstrap support values在有些family中高,bootstrap sup ...
- Xen入门系列二【使用 virt-install 安装虚拟机】
系统环境:Centos 6.5 + Xen4Centos安装方式 相关链接:Xen4Centos方式安装Xen请查看:http://www.cnblogs.com/hackboy/p/3662432. ...
- iOS动画效果集合、 通过摄像头获取心率、仿淘宝滑动样式、瀑布流、分类切换布局等源码
iOS精选源码 动画知识运用及常见动画效果收集 较为美观的多级展开列表 MUImageCache -简单轻量的图片缓存方案 iOS 瀑布流之栅格布局 一用就上瘾的JXCategoryView iOS ...
- 一:MYsql登录,服务开启和停止
字段的属性: 1:名称 2:数据类型 3:长度 4:约束 SQL的分类:(结构化查询语言) 1:数据查询语言DQL select 2:数据操纵语言DML insert delete u ...
- 微软科学家Leslie Lamport荣获2013年图灵奖
Lamport荣获2013年图灵奖" title="微软科学家Leslie Lamport荣获2013年图灵奖"> 编者按:Leslie Lamport,新晋图灵奖 ...
- 牛客-Corn Fields
题目传送门 sol:状压和动规,把每一行的m个01压缩成一个int 状压dp #include "bits/stdc++.h" using namespace std; ; con ...
- jsonp和callback的使用
这两天用 Jquery 跨域取数据的时候,经常碰到 invalid label 这个错误,十分的郁闷,老是取不到服务器端发送回来的 json 值, 一般跨域用到的两个方法为:$.ajax 和$.get ...
- cs231n spring 2017 lecture11 Detection and Segmentation
1. Semantic Segmentation 把每个像素分类到某个语义. 为了减少运算量,会先降采样再升采样.降采样一般用池化层,升采样有各种“Unpooling”.“Transpose Conv ...
- VSAN磁盘扩容与收缩
删除闪存盘后,整个磁盘组都会被删除 假如一个磁盘组里面只有一块HDD盘,删除此HDD盘,磁盘组也只接被删除 可以整体删除整个磁盘组