字符串的replace方法应用浅析


Posted in Javascript onDecember 06, 2011

这两个参数都是必须的,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方法。
Javascript 相关文章推荐
javascript Array.sort() 跨浏览器下需要考虑的问题
Dec 07 Javascript
学习并汇集javascript匿名函数
Nov 25 Javascript
Js实现手机发送验证码时按钮延迟操作
Jun 20 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
Nov 24 Javascript
Javascript基础教程之比较null和undefined值
May 16 Javascript
JavaScript实现复制或剪切内容到剪贴板功能的方法
May 23 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
Mar 09 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
Jul 11 Javascript
vue实现多个元素或多个组件之间动画效果
Sep 25 Javascript
关于vue2强制刷新,解决页面不会重新渲染的问题
Oct 29 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
Jan 06 Javascript
Vue 打包后相对路径的引用问题
Jun 05 Vue.js
js滚动条回到顶部的代码
Dec 06 #Javascript
javascript检测浏览器flash版本的实现代码
Dec 06 #Javascript
javascript 随机展示头像实现代码
Dec 06 #Javascript
jQuery中需要注意的细节问题小结
Dec 06 #Javascript
jQuery load方法用法集锦
Dec 06 #Javascript
基于JQuery实现的类似购物商城的购物车
Dec 06 #Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
Dec 06 #Javascript
You might like
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
HTML中不支持静态Expando的元素的问题
2007/03/08 Javascript
jQuery+jqmodal弹出窗口实现代码分明
2010/06/14 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
用js来获取上传的文件名纯粹是为了美化而用
2013/10/23 Javascript
jQuery中:gt选择器用法实例
2014/12/29 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
2015/07/05 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
2016/12/27 Javascript
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
Vue.set() this.$set()引发的视图更新思考及注意事项
2018/08/30 Javascript
javascript中this的用法实践分析
2019/07/29 Javascript
node运行js获得输出的三种方式示例详解
2020/07/02 Javascript
使用TS来编写express服务器的方法步骤
2020/10/29 Javascript
vue动态设置路由权限的主要思路
2021/01/13 Vue.js
Pandas探索之高性能函数eval和query解析
2017/10/28 Python
python logging日志模块的详解
2017/10/29 Python
python smtplib模块自动收发邮件功能(二)
2018/05/22 Python
python简单实现AES加密和解密
2019/03/28 Python
python使用原始套接字发送二层包(链路层帧)的方法
2019/07/22 Python
Pytorch 实现数据集自定义读取
2020/01/18 Python
Baby Tulai澳大利亚:美国婴儿背带品牌
2018/10/15 全球购物
澳大利亚家居用品零售商:Harris Scarfe
2020/10/10 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
sort命令的作用和用法
2013/08/25 面试题
护士辞职信范文
2014/01/19 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书
高中历史教学反思
2014/02/08 职场文书
安全演讲稿大全
2014/05/09 职场文书
催款函怎么写
2015/06/24 职场文书
《成长的天空》读后感3篇
2019/12/06 职场文书