字符串的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 相关文章推荐
模仿JQuery sortable效果 代码有错但值得看看
Nov 05 Javascript
弹出层之1:JQuery.Boxy (一) 使用介绍
Oct 06 Javascript
jQuery源码分析-05异步队列 Deferred 使用介绍
Nov 14 Javascript
js控制CSS样式属性语法对照表
Dec 11 Javascript
jquery改变disabled的boolean状态的三种方法
Dec 13 Javascript
AngularJs定制样式插入到ueditor中的问题小结
Aug 01 Javascript
bootstrap fileinput 插件使用项目总结(经验)
Feb 22 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
Jun 06 Javascript
jQuery实现table表格信息的展开和缩小功能示例
Jul 21 jQuery
mpvue写一个CPASS小程序的示例
Sep 04 Javascript
JS中使用react-tooltip插件实现鼠标悬浮显示框
May 15 Javascript
Vue3.0 响应式系统源码逐行分析讲解
Oct 14 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 验证码实例代码
2010/06/01 PHP
ThinkPHP模板判断输出Defined标签用法详解
2014/06/30 PHP
PHP统计目录中文件以及目录中目录大小的方法
2016/01/09 PHP
Yii2框架实现数据库常用操作总结
2017/02/08 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
2018/05/28 PHP
js 中{},[]中括号,大括号使用详解
2011/05/12 Javascript
JavaScript函数模式详解
2014/11/07 Javascript
轻松创建nodejs服务器(3):代码模块化
2014/12/18 NodeJs
JavaScript监听和禁用浏览器回车事件实例
2015/01/31 Javascript
AngularJS内建服务$location及其功能详解
2016/07/01 Javascript
学习Angular中作用域需要注意的坑
2016/08/17 Javascript
Vue过滤器的用法和自定义过滤器使用
2017/02/08 Javascript
原生JS实现图片懒加载(lazyload)实例
2017/06/13 Javascript
详解vue2.0的Element UI的表格table列时间戳格式化
2017/06/13 Javascript
jQuery完成表单验证的实例代码(纯代码)
2017/09/30 jQuery
vue实现图片滚动的示例代码(类似走马灯效果)
2018/03/03 Javascript
详解JavaScript的数据类型以及数据类型的转换
2019/04/20 Javascript
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
Node.JS用纯JavaScript生成图片或滑块式验证码功能
2019/09/12 Javascript
[03:32]2014DOTA2西雅图邀请赛 CIS外卡赛赛前black专访
2014/07/09 DOTA
Windows下Python使用Pandas模块操作Excel文件的教程
2016/05/31 Python
python2.7实现爬虫网页数据
2018/05/25 Python
python中dict字典的查询键值对 遍历 排序 创建 访问 更新 删除基础操作方法
2018/09/13 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
如何使用html5与css3完成google涂鸦动画
2012/12/16 HTML / CSS
英国派对礼服和连衣裙购物网站:TFNC London
2018/07/07 全球购物
信息部岗位职责
2013/11/12 职场文书
专科文秘应届生求职信
2013/11/18 职场文书
银行反四风对照检查材料
2014/09/29 职场文书
股份转让协议书范本
2015/01/27 职场文书
企业爱心捐款倡议书
2015/04/27 职场文书
nginx 防盗链防爬虫配置详解
2021/03/31 Servers
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL
如何用六步教会你使用python爬虫爬取数据
2022/04/06 Python
python创建字典及相关管理操作
2022/04/13 Python