字符串的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 相关文章推荐
FireFox下XML对象转化成字符串的解决方法
Dec 09 Javascript
jquery高效反选具体实现
May 05 Javascript
JavaScript 垃圾回收机制分析
Oct 10 Javascript
JS小功能(checkbox实现全选和全取消)实例代码
Nov 28 Javascript
js判断子窗体是否关闭的方法
Aug 11 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
Mar 07 Javascript
JavaScript数组方法总结分析
May 06 Javascript
JavaScript运动框架 多物体任意值运动(三)
May 17 Javascript
微信小程序表单验证功能完整实例
Dec 01 Javascript
vue 实现类似淘宝星级评分的示例
Mar 01 Javascript
几个你不知道的技巧助你写出更优雅的vue.js代码
Jun 11 Javascript
JavaScript 链表定义与使用方法示例
Apr 28 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
PHP 小心urldecode引发的SQL注入漏洞
2011/10/27 PHP
PHP编程函数安全篇
2013/01/08 PHP
php使用pdo连接并查询sql数据库的方法
2014/12/24 PHP
php实现对象克隆的方法
2015/06/20 PHP
ThinkPHP实现更新数据实例详解(demo)
2016/06/29 PHP
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
2013/11/22 Javascript
使用AngularJS来实现HTML页面嵌套的方法
2015/06/17 Javascript
javascript实现input file上传图片预览效果
2015/12/31 Javascript
js中利用tagname和id获取元素的方法
2016/01/03 Javascript
javascript弹性运动效果简单实现方法
2016/01/08 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
2016/05/23 Javascript
BootStrap表单宽度设置方法
2017/03/10 Javascript
详解Vue iview IE浏览器不兼容报错(Iview Bable polyfill)
2019/01/07 Javascript
深入koa-bodyparser原理解析
2019/01/16 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
layui表格内放置图片,并点击放大的实例
2019/09/10 Javascript
vue-cli3配置favicon.ico和title的流程
2020/10/27 Javascript
[05:06]TI4西雅图DOTA2前线报道 海涛密探LGD训练
2014/07/09 DOTA
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
2015/03/30 Python
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
Python中模块与包有相同名字的处理方法
2017/05/05 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
python 使用装饰器并记录log的示例代码
2019/07/12 Python
python实现动态数组的示例代码
2019/07/15 Python
python xlwt如何设置单元格的自定义背景颜色
2019/09/03 Python
python去除删除数据中\u0000\u0001等unicode字符串的代码
2020/03/06 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
CSS3过渡transition效果实例介绍
2016/05/03 HTML / CSS
Skyscanner阿联酋:全球领先的旅游搜索平台
2017/11/25 全球购物
本科毕业生求职自荐信
2014/02/03 职场文书
优秀员工评语
2014/02/10 职场文书
2014社区三八妇女节活动方案
2014/03/30 职场文书
保护环境的标语
2014/06/09 职场文书
2015军训通讯稿大全
2015/07/18 职场文书
Python matplotlib可视化之绘制韦恩图
2022/02/24 Python
Android自定义scrollview实现回弹效果
2022/04/01 Java/Android