资讯专栏INFORMATION COLUMN

原生js实现replace方法

Honwhy / 2919人阅读

摘要:今天看到有人提问的方法怎么实现的,自己就试了试手册里的对象的介绍大概是这样第一个参数声明了要替换的模式的对象。第二个参数一个字符串,声明的是替换文本或生成替换文本的函数。在调用非全局对象的方法时,返回的数组与调用方法返回的方法相同。

今天看到有人提问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)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/52055.html

相关文章

  • 原生js实现replace方法

    摘要:今天看到有人提问的方法怎么实现的,自己就试了试手册里的对象的介绍大概是这样第一个参数声明了要替换的模式的对象。第二个参数一个字符串,声明的是替换文本或生成替换文本的函数。在调用非全局对象的方法时,返回的数组与调用方法返回的方法相同。 今天看到有人提问js的replace方法怎么实现的,自己就试了试js手册里的String对象的介绍replace大概是这样: string.replac...

    teren 评论0 收藏0
  • 14行实现js原生语法前端模板引擎

    最近开发前端一直用的前端模板引擎; 一直使用的 TPPL 模板引擎 源代码如下: function tppl(tpl, _data) { tpl = tpl.replace(/()/g, >); var data = _data || {}; if (typeof data !== object) { console.log(TEFinal -> data ...

    hyuan 评论0 收藏0
  • 原生 JS 实现 MVVM 框架2——单向绑定

    摘要:上一篇写了实现框架的一些基本概念本篇用代码来实现一个完整的框架思考假设有如下代码,里面的会和试图中的一一映射,修改的值,会直接引起试图中对应数据的变化如何实现上述呢回想下这篇讲的观察者模式和数据监听主题是什么观察者是什么观察者何时订阅主题主 上一篇写了实现 MVVM 框架的一些基本概念 本篇用代码来实现一个完整的 MVVM 框架 思考 假设有如下代码,data里面的name会和试图中的...

    Zoom 评论0 收藏0
  • 放弃jQuery, 使用原生js

    摘要:随着的逐渐淘汰,的兴起,以及侧重点放在了移动端,可能变的不在那么重要,原生一样很好用。下面介绍几个原生替换的方法。 随着IE6、7、8的逐渐淘汰,HTML5的兴起,以及侧重点放在了移动端,jQuery可能变的不在那么重要,原生一样很好用。下面介绍几个原生替换jq的方法。 获取元素 //jQuery $(.xxx); //class获取 $(#xxx); //id获取 $(....

    mumumu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<