今天看到有人提问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. 记录ionic 最小化应用时所遇的问题

    ionic3与ionic4最小化插件安装不一样: ionic3安装方法: $ ionic cordova plugin add cordova-plugin-appminimize $ npm ins ...

  2. HttpClient简介与案例分析

    HttpClient简介 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 jav ...

  3. 线程、volatile与synchronized、Lock

    目录 线程 1.概念: 2.线程生命周期: 3.线程调度 4.线程实现 4.1.实现方式 4.2.之间的区别: 5.线程安全 5.1.volatile与synchronized 5.1.synchro ...

  4. Qt QString 与 const char* 类型的转换

    QString DATA; std::string str = DATA.toStdString(); const char* ch = str.c_str();

  5. Nginx笔记总结二十一:隐藏或者混淆nginx返回的Server信息

    [root@localhost nginx-]# vi src/http/ngx_http_header_filter_module.c 修改:49-50行 static char ngx_http_ ...

  6. SHELL用法七(Sed语句)

    1.SHELL编程Sed语句案例实战 1)SHELL编程四剑客之二的Sed工具,主要是用于Linux系统文本文件的编辑. 打印的,也称为非交互模式编辑器(vi|vim交互模式编辑器),Sed工具的语法 ...

  7. IOC @Autowired/@Resource/@Qulified的用法实例

    首先要知道另一个东西,default-autowire,它是在xml文件中进行配置的,可以设置为byName.byType.constructor和autodetect:比如byName,不用显式的在 ...

  8. Flash Builder 使用

    1. 解决编译慢的问题:用记事本打开安装目录下的 FlashBuilder.ini ,将里面设置的容量都扩大一半,如-Xms256m改为 -Xms512m,另外几项类似修改: 定位到相应版本的sdks ...

  9. IP地址0.0.0.0表示什么

    参考RFC文档: 0.0.0.0/8 - Addresses in this block refer to source hosts on "this"network. Addre ...

  10. 来自澳洲的数据秀场:记KDD 2015大会

    作者:微软亚洲研究院实习生 王英子 南半球最大城市和数据挖掘界顶级会议的浪漫碰撞 悉尼,作为澳大利亚第一大城市及新南威尔士州首府,澳大利亚的经济.金融.航运和旅游中心,同时还是南半球最大的城市和重要的 ...