字符串的replace方法应用浅析 |
本文标签:字符串,replace 这两个参数都是必须的,replace() 方法的参数 replacement 可以是函数而不是字符串 。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用 。该函数的第一个参数是匹配模式的字符串 。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数 。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置 。最后一个参数是 stringObject 本身 。对于replacement是函数的情况,给我们提供了很大的便利 。 这有一个很简单的交换两个单词顺序的例子,如果不用repalce可以这么做: 复制代码 代码如下: (function(){ var str = click dblclick; var result = str.split(/\b/).reverse().join() console.log(result); })() 这么做略显麻烦,用replace处理则显得清爽许多: 复制代码 代码如下: (function(){ var str = click dblclick; var result = str.replace(/\b(\w+)(\s+)(\w+)\b/,$3$2$1); console.log(result); })(); 再看另一个例子——给数字加上千分位: 复制代码 代码如下: (function(){ var number = 12345678900; var result = (+number).replace(/(\d)(?=(\d{3})+$)/g,$1,); console.log(result); })(); 不过现在要扯的是replacement作为函数的用法,所以多此一举的把上面的形式改成函数的形式: 复制代码 代码如下: (function(){ var str = click dblclick; var result = str.replace(/\b(\w+)(\s+)(\w+)\b/,function(all,$1,$2,$3){ return $3+$2+$1; }); console.log(result); })(); (function(){ var number = 12345678900; var result = (+number).replace(/(\d)(?=(\d{3})+$)/g,function(all,$1){ return $1 + ,; }); console.log(result); })(); 所以replace无非是捕获匹配的项然后经过处理,作为返回值进行替换,只不过是函数的比较给力 。 下面看一个比较实用的例子,大多数语言都有的格式化输出,比如C语言的printf: 复制代码 代码如下: (function(){ var str = %s may have gone, but there is a time of %s; var result = str.replace(/(%s)/g,function(){ return replacement; }) console.log(result); })() 这里有个问题就是,%s都是一样的,替换出来都是一样的,而且我们只能按照顺序来判断被替换的是哪一部分,如果添加一段,那么后面所有的都得变 。所以我们得传个变量进去 。 复制代码 代码如下: (function(){ var array = [Swallows,return]; var i = 0; var str = %s may have gone, but there is a time of %s; var result = str.replace(/(%s)/g,function(){ return array[i++]; }) console.log(result); })(); (function(){ var str = #{what} may have gone, but there is a time of #{how}; var obj = { what : Swallows, how : return } var result = str.replace(/(?:#{(\w+)})/g,function(all,$1){ return obj[$1]; }) console.log( result); })(); 显然用对象的方法要靠谱一点 。 同时,js并没有那么严格的类型要求,所以,%s这种形式也成为了局限 。直接摈弃,换成我们容易理解的形式 。 伪装成函数的样子就是: 复制代码 代码如下: (function(){ function gsub(str,replaceObj){ return str.replace(/(?:#{(\w+)})/g,function(all,$1){ return replaceObj[$1]; }) } console.log(gsub结果:,gsub(#{what} may have gone, but there is a time of #{how},{ what : Swallows, how : return })) })(); 上面的gsub借用了Prototype中的gsub方法名字,虽然Prototype中的gsub并不是用的replace,但是形式上还是很像的 。 现在面临的一个问题是: #{what}这种形式的冲突问题,有可能字符串里面刚好就有这种形式的字符串,如果不作处理,后果大家都懂的 。 第一种解决办法:正则里面有转义字符,我们也可以有,所以我们干脆在不需要的替换的部分前面加上\ 第二种解决办法:让使用者自定义一个标志来替换#{}的标志,从而避免冲突 。 看第一种方法: 复制代码 代码如下: (function(){ var str = #{what} may have gone, but there is a time of #{how},\\#{reserve}; function gsub(str,replaceObj){ return str.replace(/(^|.)(?:#{(\w+)})/g,function(all,$1,$2){ if($1 == \\){ return #{ + $2 +}; } return $1 + replaceObj[$2]; }) } console.log(gsub结果:,gsub(str,{ what : Swallows, how : return })) })(); 上面需要注意的就是\在字符串中也是转义字符,写的时候也需要转义 。 第二种方法: 我们把#{what}换成<%what%>的形式 。 复制代码 代码如下: (function(){ function gsub(str,replaceObj,regexp){ regexp = regexp || /(?:#{(\w+)})/g; return str.replace(regexp,function(all,$1){ return replaceObj[$1]; }) } var str = <%what%> may have gone, but there is a time of <%how%>,#{reserve}; console.log(gsub结果:,gsub(str,{ what : Swallows, how : return },/(?:<%(\w+)%>)/g)) })(); 现在把gsub挂到String的原型上面 复制代码 代码如下: String.prototype.gsub = function(replaceObj,regexp){ regexp = regexp || /(^|.)(?:(#{)(\w+)(}))/g; return this.replace(regexp,function(all,$1,$2,$3,$4){ if($1 == \\){ return $2+$3+$4; } return $1 + replaceObj[$3] ; }) } var str = <%what%> may have gone, but there is a time of <%how%>,\\<%how%>,#{how}; var obj = { what : Swallows, how : return } console.log(测试1:,str.gsub(obj,/(^|.)(?:(<%)(\w+)(%>))/g)); //Swallows may have gone, but there is a time of return,<%how%>,#{how} console.log(测试2:,str.gsub(obj)); //<%what%> may have gone, but there is a time of <%how%>,\<%how%>,return 嘿嘿,貌似和Prototype中的gsub很像了,不过Prototype中的gsub复杂一些,原理也不一致,熟悉一下,待会再仔细分析Prototype中的gsub方法 。 |