字符串的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 相关文章推荐
JS BASE64编码 window.atob(), window.btoa()
Mar 09 Javascript
Javascript之文件操作
Mar 07 Javascript
基于JQuery实现CheckBox全选全不选
Jun 27 Javascript
js获取当前日期代码适用于网页头部
Jun 27 Javascript
简介JavaScript中Math.LOG10E属性的使用
Jun 14 Javascript
jQuery EasyUI Dialog拖不下来如何解决
Sep 28 Javascript
PHP获取当前页面完整URL的方法
Dec 02 Javascript
Vue + Webpack + Vue-loader学习教程之相关配置篇
Mar 14 Javascript
深入理解Vue 的条件渲染和列表渲染
Sep 01 Javascript
实例分析Array.from(arr)与[...arr]到底有何不同
Apr 09 Javascript
Vue实现移动端拖拽交换位置
Jul 29 Javascript
jquery简易手风琴插件的封装
Oct 13 jQuery
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
ThinkPHP实例化模型的四种方法概述
2014/08/22 PHP
php的lavarel框架中join和orWhere的用法
2020/12/28 PHP
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
jquery json 实例代码
2010/12/02 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
jquery实现多级下拉菜单的实例代码
2013/10/02 Javascript
JS实现OCX控件的事件响应示例
2014/09/17 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
apply和call方法定义及apply和call方法的区别
2015/11/15 Javascript
利用React-router+Webpack快速构建react程序
2016/10/27 Javascript
微信小程序 基础知识css样式media标签
2017/02/15 Javascript
JavaScript组件开发之输入框加候选框
2017/03/10 Javascript
vue-router 中router-view不能渲染的解决方法
2017/05/23 Javascript
jqgrid实现简单的单行编辑功能
2017/09/30 Javascript
vue使用rem实现 移动端屏幕适配
2018/09/26 Javascript
webpack 开发和生产并行设置的方法
2018/11/08 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
2019/01/08 Javascript
谈谈JavaScript中super(props)的重要性
2019/02/12 Javascript
Vue项目中使用flow做类型检测的方法
2020/03/18 Javascript
[55:11]完美世界DOTA2联赛PWL S2 SZ vs LBZS 第一场 11.26
2020/11/30 DOTA
提升Python程序运行效率的6个方法
2015/03/31 Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
2017/08/23 Python
Python之list对应元素求和的方法
2018/06/28 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
2019/01/05 Python
python读取txt文件并取其某一列数据的示例
2019/02/19 Python
python五子棋游戏的设计与实现
2019/06/18 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
html5 canvas合成海报所遇问题及解决方案总结
2017/08/03 HTML / CSS
地理教师岗位职责
2014/03/16 职场文书
四群教育工作实施方案
2014/03/26 职场文书
环境卫生倡议书
2014/08/29 职场文书
学校运动会广播稿100条
2014/09/14 职场文书
党员反腐倡廉学习心得体会
2015/08/15 职场文书
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
2021/06/30 SQL Server
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL
Mac电脑OS系统下安装Nginx的详细教程
2022/04/14 Servers