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似乎更强大
分享到:
相关推荐
String.replace( ) 简介 语法: 代码如下: string.replace(regexp, replacement) regexp :您要执行替换操作的正则... String.replace( ) 的简单用法 代码如下: var text = “javascript 非常强大 !”; text.repl
99.string.replace(regExpression,replaceString)替换现有字符串. 100.string.split(分隔符)返回一个数组存储值. 101.string.substr(start[,length])取从第几位到指定长度的字符串. 102.string.toLowerCase()使字符...
代码如下: 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
stringObject.replace(regexp/substr,replacement)参数 描述 regexp/substr 必需。规定子字符串或要替换的模式的 RegExp 对象。 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被...
字符串替换异步知道如何等待的“ string” .replace()函数安装$ npm install string-replace-async用法let replaceAsync = require ( "string-replace-async" ) ;await replaceAsync ( "#rebeccapurple" , / # ( \...
replace方法是javascript涉及到正则表达式中较为复杂的一个方法,严格上说应该是string对象的方法。只不过牵扯到正则的时候比较多一些。需要我们灵活的使用。 语法: stringObj.replace(regexp/substr,replacement)...
语法:string.replace(subStr/reg,replaceStr/function) 第一个参数可以是字符串的子字符串,也可以是一个正则表达式,第二个参数可以是一个字符串或者一个处理方法,下面我们分别看看 代码如下:[removed](‘1234’....
源于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 ...
JavaScript String.replace函数作用是将源自符串中的match替换为replacement并返回替换后的字符串,使用介绍如下,不会的朋友可以了解下哈
string.prototype.replaceall 用于String.prototype.replaceAll的ES Proposal规范填充程序。 如果不可用或不String.prototype....// replaceAll and replace are the same, when given a global regex to replace as
replaceString)替换现有字符串. 100.string.split(分隔符)返回一个数组存储值. 101.string.substr(start[,length])取从第几位到指定长度的字符串. 102.string.toLowerCase()使字符串全部变为小写. 103....
本文实例讲述了JavaScript中String.prototype用法。分享给大家供大家参考。具体如下: // 返回字符的长度,一个中文算2个 String.prototype.ChineseLength=function() { return this.replace(/[^\x00-\xff]/g,"**...
替换字符串替换字符串中的所有子字符串匹配项与String#replace()类似,但支持替换多个匹配项。 通过将字符串放入带有全局标志的RegExp构造函数中并将其传递给String#replace() ,可以实现类似的效果,但是无论如何,...
99.string.replace(regExpression,replaceString)替换现有字符串. 100.string.split(分隔符)返回一个数组存储值. 101.string.substr(start[,length])取从第几位到指定长度的字符串. 102.string.toLowerCase()使字符...
javascript笔记 String类replace函数的一些事.docx
string.replace(regexp, replacement) 参数: regexp: RegExp对象或者字符串 replacement: 替换文本的字符串,或者一个函数,用于在调用时生成对应的替换文本。 返回: 返回一个替换好的新字符串 描述: ...
StringJS Swift扩展库 一个很小的Swift扩展库,实现了我们惯用JavaScript String函数。 您可以在阅读有关JavaScript String函数的文档。 可用功能 length -> Int (实例变量) ... replace(what:String, w
方法: string.replace(new RegExp(oldString,”gm”),newString)) gm 分别代表: g=global, m=multiLine 大致上方法就是这样的,可以实现替换全部指定字串 另一个简单的验证JS的方法: 在浏览器地址栏输入 [removed]...