字符串的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网页关闭时提醒效果脚本
Oct 22 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
Jun 20 Javascript
jQuery 遍历-nextUntil()方法以及prevUntil()方法的使用介绍
Apr 26 Javascript
js 动态加载事件的几种方法总结
Dec 25 Javascript
深入理解JS中的变量及作用域、undefined与null
Mar 04 Javascript
深入剖析JavaScript编程中的对象概念
Oct 21 Javascript
webpack+vue.js实现组件化详解
Oct 12 Javascript
基于Vuejs和Element的注册插件的编写方法
Jul 03 Javascript
深入浅析ES6 Class 中的 super 关键字
Oct 20 Javascript
浅谈webpack4 图片处理汇总
Sep 12 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
May 17 Javascript
JavaScript实现多文件下载方法解析
Aug 07 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
MySql中正则表达式的使用方法描述
2008/07/30 PHP
PHP教程 变量定义
2009/10/23 PHP
php小经验:解析preg_match与preg_match_all 函数
2013/06/29 PHP
一个比较不错的PHP日历类分享
2014/11/18 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
学习php设计模式 php实现适配器模式
2015/12/07 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
用js自动判断浏览器分辨率的代码
2007/01/28 Javascript
Bookmarklet实现启动jQuery(模仿 云输入法)
2010/09/15 Javascript
使用jQuery在移动页面上添加按钮和给按钮添加图标
2015/12/04 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
React和Vue中监听变量变化的方法
2018/11/14 Javascript
layui 解决富文本框form表单提交为空的问题
2019/10/26 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
vue点击Dashboard不同内容 跳转到同一表格的实例
2020/11/13 Javascript
python实现图片处理和特征提取详解
2017/11/13 Python
python如何统计序列中元素
2020/07/31 Python
Python切片操作深入详解
2018/07/27 Python
python 拼接文件路径的方法
2018/10/23 Python
pygame游戏之旅 计算游戏中躲过的障碍数量
2018/11/20 Python
Django 自定义404 500等错误页面的实现
2020/03/08 Python
使用Matplotlib绘制不同颜色的带箭头的线实例
2020/04/17 Python
玩具反斗城葡萄牙官方商城:Toys"R"Us葡萄牙
2016/10/21 全球购物
英国的领先快速时尚零售商:In The Style
2019/03/25 全球购物
中专毕业生求职简历的自我评价
2013/10/21 职场文书
中学实习教师自我鉴定
2013/12/12 职场文书
展会邀请函范文
2014/01/26 职场文书
理工类毕业自我鉴定
2014/02/20 职场文书
犯错检讨书
2014/02/21 职场文书
超市理货员岗位职责
2014/07/04 职场文书
小学运动会入场口号
2015/12/24 职场文书
2016年社区“我们的节日·中秋节”活动总结
2016/04/05 职场文书
python 制作一个gui界面的翻译工具
2021/05/14 Python
Python手拉手教你爬取贝壳房源数据的实战教程
2021/05/21 Python
PHP实现rar解压读取扩展包小结
2021/06/03 PHP