`
lucane
  • 浏览: 121702 次
  • 性别: Icon_minigender_1
  • 来自: 江湖
社区版块
存档分类
最新评论

JavaScript:String.replace

阅读更多
JavaScript中的String.replace(a, b)函数默认是只执行一次替换,即在某个字符串中检索a子串,然后再用b来替换a,只执行一次这样的操作,即使后面跟着多个a,它也不会继续往后面检索,其实我这么说是不正确的,准确的理解大家可以查看
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace
看看replace方法的参数就明白了

但是如果大家没有注意这个函数的说明,就很容易认为这个函数有类似于replaceAll这样的功能,并且默认是具有这样的功能的
并且还有人为此付出过代价
所以说Gareth Heyes才说这个方法是Bad Design
http://www.thespanner.co.uk/2010/09/27/string-replace-javascript-bad-design/
并且给了个这个函数的patch版本,默认是执行全文替换

其实我觉得一定要开发人员清楚函数的功能这样才不容易犯错,即使默认执行的是全文替换,在有些不需要全文替换的情况下还是有人会出错

不过既然给出patch了,作为菜鸟慢慢飞的我还是想看下,做事总会有理由的,否则人家吃力不讨好,何必呢。

下面是作者的代码,我只是COPY过来了,在看的时候不懂了,希望看到这里的人指点指点小弟啦,后面会有问题

String.prototype.replace = (function(r){
    return function(find, replace, replaceOnce) {
        if(typeof find == 'string' && !replaceOnce) {
            find = r.apply(find, [/[\[\]^$*+.?(){}\\\-]/g,function(c) { return '\\'+c; }]);
            find = new RegExp(find, 'g');
        } else if(typeof find == 'object' && !replaceOnce && !find.global) {
            find = new RegExp(find.source, 'g');
        }
        return r.apply(this, [find,replace]);
    };
})(String.prototype.replace);


函数使用样例,照搬过来的
alert('aaaabbbbb'.replace(/a/,''))


利用把匿名函数执行结果赋值给一个引用变量的方式来定义一个函数,这里就相当于它把原来的replace函数给覆盖了
实际后面的匿名函数返回了一个函数,该函数可以接受三个参数,比较清楚
现在我们把这个函数分解掉,只拿出关键的部分,即:

function(find, replace, replaceOnce) {
    if(typeof find == 'string' && !replaceOnce) {
        find = r.apply(find, [/[\[\]^$*+.?(){}\\\-]/g,function(c) { return '\\'+c; }]);
        find = new RegExp(find, 'g');
    } else if(typeof find == 'object' && !replaceOnce && !find.global) {
        find = new RegExp(find.source, 'g');
    }
    return r.apply(this, [find,replace]);
};


这个当中的r实际上就是String.prototype.replace,即原生态的replace函数

这个函数有两个if,实际上会有三种情况
第一:当传入的要被替换的东西是字符串,并且没有明确指出只替换一次的时候,它执行全文替换,即替换所有出现find的地方
第二:当传入的是对象(实际上这个对象已经基本确认为正则表达式对象,所以才会有后面的global属性),并且没有明确指出只替换一次的时候,并且该对象的global属性也没有为true的时候,即替换所有出现find的地方
第三:其他情况替换第一次出现的find(默认功能)

从这里开始我就不是很清楚了

这里它是在替换之前对find进行了一些处理,我们继续分解
第一种情况,这里出现了一个数组参数,分别是个正则表达式和一个函数
我们只看这个正则表达式的意思

我的理解是对find参数中的遇到的这些东西/[\[\]^$*+.?(){}\\\-]/进行全文替换
OMG,一个参数中会有这么复杂的情况吗?
誰能帮我解释解释这个正则表达式的含义啊,万分感谢


只要能把这个搞明白后面的就很简单了

第二种情况,这里用了typeof来侦测find的类型,这里又引申出来另外一个东西

typeof(正则表达式对象),这个会返回什么?

我简单做了下测试,结果如下
引用

// IE8                object
// FF3.6              object
// Opera9.26          object
// Chromium4.0      function
// jsdb             function


但是,typeof(正则表达式对象) == "object",这个又会是什么?
同样简单测试:
引用

// IE8                  true
// FF3.6                true
// Opera9.26            true
// Chromium4.0          true
// jsdb                false


唯一一个出现false的东西,它不是浏览器,还好
为什么Chromium4.0在这个问题上步调不一致呢

然后我又测试了另外一个问题,typeof(/a/) == "function"
在Chromium4.0 上返回false,我下我就糊涂了
难道跟Chromium的JS引擎和正则表达式引擎有关,等待高人指点一二

看来这应当是bug


第三种情况,没啥好说的,就是默认的情况

到这里就剩下一个正则和一个typeof(正则)弄不明白了

其中这个正则表达式,我还试着继续分解了下,发现弄不下去了
/[\[\]^$*+.?(){}\\\-]/g

[\[\]^$*+.?(){}\\\-]

下面任意一种情况出现
[
]
...
后面的我两眼一绿,就分不出来了

后来又用工具测了下,让我又晕了会
实际上我觉得这里前后的“/”和“/g”本来就应当是匹配所有,即传入的参数中如果包括下面的任意字符
引用
[
]
^
$
*
+
.
?
(
)
{
}
\
-


都会被转义成普通字符,而不是正则表达式当中的元字符,从而构造新的正则表达式

RegexBuddy 写道
Match the character “/” literally
Match a single character present in the list below
   A [ character
   A ] character
   One of the characters “^$*+.?(){}”
   A \ character
   A - character
Match the characters “/g” literally


RegexBuddy(The Regex Coach)里面分析出来的前后“/”和“/g”,它直接把认为是普通字符了,让我有点迷糊,可能跟工具本身具有的功能相关(工具已经具有可以选择是否忽略大小写,全局匹配,多行匹配这些功能,所以它直接把这些表达式文字上写的这些特殊符号当成普通字符了)
现在总算是明白这段正则的含义和用途了

P.S. Irregexp
The Regex Coach和RegexBuddy都是我在使用的正则表达式工具,RegexBuddy似乎更强大

分享到:
评论

相关推荐

    Javascript String.replace的妙用

    String.replace( ) 简介 语法: 代码如下: string.replace(regexp, replacement) regexp :您要执行替换操作的正则... String.replace( ) 的简单用法 代码如下: var text = “javascript 非常强大 !”; text.repl

    js中字符替换函数String.replace()使用技巧

    在JavaScript中,`String.prototype.replace()` 是一个非常重要的字符串方法,用于在字符串中查找匹配的模式(可以是正则表达式或子字符串)并替换它们。这个方法的使用技巧广泛,能够实现各种复杂的字符串处理需求...

    js中字符替换函数String.replace()使用技巧.docx

    JavaScript中的`String.prototype.replace()`函数是一个非常实用的工具,它允许开发者在字符串中找到特定的字符或模式,并将其替换为其他字符或字符串。这个方法在前端开发、后端开发以及各种JavaScript相关的应用...

    107个常用javascript语句

    99.string.replace(regExpression,replaceString)替换现有字符串. 100.string.split(分隔符)返回一个数组存储值. 101.string.substr(start[,length])取从第几位到指定长度的字符串. 102.string.toLowerCase()使字符...

    Js中去掉空格经典代码

    为了方便使用,这里采用扩展JavaScript原生`String`对象的方法实现,即通过扩展`String.prototype`来实现这些功能: ```javascript String.prototype.Trim = function () { return this.replace(/(^\s*)|(\s*$)/g,...

    为javascript添加String.Format方法

    代码如下: String.format = function() { if( arguments.length == 0 ) { return null;... str = str.replace(re, arguments[i]); } return str; } 使用方式 : String.format(‘Hello. My name is {0} {1}.’, firs

    string-replace-async:异步String.prototype.replace()

    字符串替换异步知道如何等待的“ string” .replace()函数安装$ npm install string-replace-async用法let replaceAsync = require ( "string-replace-async" ) ;await replaceAsync ( "#rebeccapurple" , / # ( \...

    javascript笔记 String类replace函数的一些事.docx

    ### JavaScript中的`String.prototype.replace`方法详解 #### 一、`replace`方法的基本用法 在JavaScript中,`String.prototype.replace`是一个非常重要的方法,用于替换字符串中的某些部分。其基本语法如下: ``...

    JavaScript String.replace函数参数实例说明

    JavaScript 中的 String.replace 方法是一个非常实用的字符串操作函数,它允许开发者将字符串中的特定内容替换成另外的内容。这个方法不仅适用于简单的文本替换,还可以处理正则表达式的匹配,提供高级的文本替换...

    matlab开发-未经许可的Javascriptstring.zip.zip

    这个"matlab开发-未经许可的Javascriptstring.zip.zip"文件可能包含了关于如何在MATLAB中使用JavaScript字符串处理技术的相关资料,尽管它提及“未经许可”,这可能意味着其中的内容可能是版权保护或者非官方的教程...

    关于JS字符串函数String.replace()

    JS字符串函数String.replace()是JavaScript中一个非常实用的字符串操作方法,它允许开发者针对字符串中的文本进行替换。这个函数对于文本处理非常重要,因为它可以应用正则表达式来实现复杂的模式匹配和替换逻辑。 ...

    js中string之正则表达式replace方法详解

    replace方法是javascript涉及到正则表达式中较为复杂的一个方法,严格上说应该是string对象的方法。只不过牵扯到正则的时候比较多一些。需要我们灵活的使用。 语法: stringObj.replace(regexp/substr,replacement)...

    JavaScript程序设计课件:String对象.pptx

    JavaScript中的String对象是编程中非常基础且重要的概念,它用于表示和操作文本数据。在JavaScript中,通过单引号或双引号包围的任何字符序列都会被视为字符串,并且它们本质上都是String构造函数的实例。本节主要...

    js中的string.format函数代码

    源于C#中的string.Format() 代码如下: String.prototype.format = function(args) { if (arguments.length>0) { var result = this; if (arguments.length == 1 && typeof (args) == “object”) { for (var key in ...

    Js里面给String添加trim()方法,实现去掉字符串两边空格

    原生的JavaScript自ECMAScript5标准引入后,就已经提供了`String.trim()`方法来去除字符串首尾的空白字符,这为开发者带来了极大的便利。然而,在此之前,或者在某些特定环境下(如旧版本的浏览器),`String.trim()...

    常用字符串处理整理.rar

    4. 查找与替换:`String.IndexOf()`查找子字符串的位置,`String.Replace()`用于替换字符串中的特定字符或子字符串。 5. 去除空白:`String.Trim()`, `String.TrimStart()`, `String.TrimEnd()`分别用于去除字符串...

    String.prototype.replaceAll:适用于String.prototype.replaceAll ESnext提案的符合规范的polyfill

    string.prototype.replaceall 用于String.prototype.replaceAll的ES Proposal规范填充程序。 如果不可用或不String.prototype....// replaceAll and replace are the same, when given a global regex to replace as

    javascript函数大全

    replaceString)替换现有字符串. 100.string.split(分隔符)返回一个数组存储值. 101.string.substr(start[,length])取从第几位到指定长度的字符串. 102.string.toLowerCase()使字符串全部变为小写. 103....

Global site tag (gtag.js) - Google Analytics