今天看到有人提问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方法的更多相关文章

  1. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  2. 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别

    一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...

  3. 原生JS中apply()方法的一个值得注意的用法

    今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...

  4. js的replace方法

    今天在项目中发现,js的replace方法,其实只是替换第一个匹配的字符: 比如 backstreetboy.replace('b','B') 得到的结果是Backstreetboy,只是替换了第一个 ...

  5. 原生JS添加节点方法与jQuery添加节点方法的比较及总结

    一.首先构建一个简单布局,来供下边讲解使用 1.HTML部分代码: <div id="div1">div1</div> <div id="d ...

  6. 原生JS实现new方法、new一个对象发生的四部、new里面常用的优先级

    一.js中new一个对象的过程 首先了解new做了什么,使用new关键字调用函数(new ClassA(…))的具体步骤: 1.创建一个新对象: var obj = {}; 2.设置新对象的const ...

  7. 【CSS进阶】原生JS getComputedStyle等方法解析

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  8. 扩展原生js的一些方法

    扩展原生js的Array类 Array.prototype.add = function(item){ this.push(item); } Array.prototype.addRange = fu ...

  9. 原生js的各种方法

    原生js操作dom元素 var link = document.createElement( "link" );link.type = "image/x-icon&quo ...

随机推荐

  1. CHINA SHOP 2019 | 奇点云“云+端”产品及解决方案赋能线下零售

    第二十一届中国零售业博览会(CHINA SHOP) 在山东青岛世界博览城盛大开幕 作为CHINA SHOP的老朋友 奇点云自然不会缺席 China Shop逛展直击灵魂“双拷问”: No.1 今年CH ...

  2. [LC] 767. Reorganize String

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  3. 吴裕雄--天生自然python学习笔记:python 用pygame模块基本绘图

    绘制几何图形是游戏包的基本功能,很多游戏角色都是由基本图形组合而成的 . 绘制矩形: pygame.draw.rect Pygam巳绘制矩形的语法为: 用基本绘图绘制一个人脸 用基本绘图功能绘制人脸 ...

  4. markdown 的一些字体

    <font face='Comic Sans MS', size=5> 看看字体 1 one Hello 2 two Hello <font face='Kristen ITC', ...

  5. FireWall2

    配置防火墙步骤: 1.给接口配置ip,开 service-manage 服务 2.把接口画在zone区域 3.配置策略 4.服务器一定要开启服务 1. interface GigabitEtherne ...

  6. [LC] 13. Roman to Integer

    Roman numerals are represented by seven different symbols: I, V, X, L, C, Dand M. Symbol Value I 1 V ...

  7. 使用框架结构之frameset

    首先,我希望在你的目录下,有4个网页,各自显示不同的内容. 如图所示: 1.html显示"火影忍者" 2.html显示"英雄联盟" 3.html显示" ...

  8. Java IO: Buffered和Data

    作者:Jakob Jenkov  译者: 李璟(jlee381344197@gmail.com) 本小节会简要概括Java IO中Buffered和data的输入输出流,主要涉及以下4个类型的流:Bu ...

  9. apache启动但是无法访问网页

    apache启动但是访问不了的问题排除??? 端口没有被占用,则需要考虑防火墙问题. 首先我们需要确保远程的Linux系统已经安装好,我们使用xshell远程SSH登录到Linux系统里,同时我们也要 ...

  10. Python-删除多级目录

    def rmdirs(top): for root, dirs, files in os.walk(top, topdown=False): # 先删除文件 for name in files: os ...