字符串的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读取中文COOKIE的解决办法
Feb 15 Javascript
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
Apr 12 Javascript
jquery序列化表单以及回调函数的使用示例
Jul 02 Javascript
jQuery Ajax()方法使用指南
Nov 19 Javascript
深入解读JavaScript中的Hoisting机制
Aug 12 Javascript
详解JavaScript数组和字符串中去除重复值的方法
Mar 07 Javascript
Bootstrap Modal遮罩弹出层(完整版)
Nov 21 Javascript
angularjs路由传值$routeParams详解
Sep 05 Javascript
jQuery实现点击自身以外区域关闭弹出层功能完整示例【改进版】
Jul 31 jQuery
关于layui 弹出层一闪而过就消失的解决方法
Sep 09 Javascript
微信小程序实现3D轮播图效果(非swiper组件)
Sep 21 Javascript
原生JS中应该禁止出现的写法
May 05 Javascript
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
10个超级有用的PHP代码片段果断收藏
2015/09/23 PHP
PHP中单例模式与工厂模式详解
2017/02/17 PHP
php xhprof使用实例详解
2019/04/15 PHP
laravel5.6实现数值转换
2019/10/23 PHP
juqery 学习之四 筛选过滤
2010/11/30 Javascript
为jquery的ajaxfileupload增加附加参数的方法
2014/03/04 Javascript
DOM基础教程之使用DOM控制表单
2015/01/20 Javascript
jQuery实现的纵向下拉菜单实例详解【附demo源码下载】
2016/07/09 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
2016/09/09 Javascript
基于iscroll.js实现下拉刷新和上拉加载效果
2016/11/28 Javascript
js倒计时显示实例
2016/12/11 Javascript
jQuery基于Ajax方式提交表单功能示例
2017/02/10 Javascript
浅谈vue的几种绑定变量的值 防止其改变的方法
2018/03/01 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
详解vue挂载到dom上会发生什么
2019/01/20 Javascript
JavaScript中的全局属性与方法深入解析
2020/06/14 Javascript
[01:00:35]2018DOTA2亚洲邀请赛3月30日B组 EffcetVSMineski
2018/03/31 DOTA
使用Python搭建虚拟环境的配置方法
2018/02/28 Python
Python实现OpenCV的安装与使用示例
2018/03/30 Python
Python3.6笔记之将程序运行结果输出到文件的方法
2018/04/22 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
2018/05/28 Python
python验证码识别教程之利用滴水算法分割图片
2018/06/05 Python
浅谈python中拼接路径os.path.join斜杠的问题
2018/10/23 Python
Python手绘可视化工具cutecharts使用实例
2019/12/05 Python
详解CSS3:overflow属性
2020/11/17 HTML / CSS
英国百安居装饰建材网上超市:B&Q
2016/09/13 全球购物
奥斯汀独木舟和皮划艇:Austin Canoe & Kayak
2018/05/22 全球购物
为什么UNION ALL比UNION快
2016/03/17 面试题
Linux文件系统类型
2012/02/15 面试题
社区学习十八大感想
2014/01/22 职场文书
晚归检讨书
2014/02/19 职场文书
运动会方阵口号
2014/06/07 职场文书
内科护士节演讲稿
2014/09/11 职场文书
2014国庆节演讲稿:祖国在我心中(400字)
2014/09/25 职场文书
区域销售大会开幕词
2016/03/04 职场文书
Golang流模式之grpc的四种数据流
2022/04/13 Golang