replace 本身是 JavaScript 字符串对象的一个方法,它允许接收两个参数
replace([RegExp|String],[String|Function])
第1 个参数可以是一个普通的字符串或是一个正则表达式 .
第2 个参数可以是一个普通的字符串或是一个回调函数 .
如果第2 个参数是回调函数,每匹配到一个结果就回调一次,每次回调都会传递以下参数:
result: 本次匹配到的结果
1, … 9: 正则表达式中有几个 () ,就会传递几个参数, 1 9 分别代表本次匹配中每个 () 提取的结果,最多 9 个
offset: 记录本次匹配的开始位置
source: 接受匹配的原始字符串
以下是replace 和 JS 正则搭配使用的几个常见经典案例:
$1$2 …表示第几个子表达式
(1 )实现字符串的 trim 函数,去除字符串两边的空格
复制代码
String.prototype.trim = function(){
// 方式一:将匹配到的每一个结果都用 "" 替换
return this.replace(/(^\s+)|(\s+$)/g,function(){
return "";
});
// 方式二:和方式一的原理相同
return this.replace(/(^\s+)|(\s+$)/g,'');
};
^s+ 表示以空格开头的连续空白字符, s+$ 表示以空格结尾的连续空白字符,加上 () 就是将匹配到的结果提取出来,由于是 | 的关系,因此这个表达式最多会 match 到两个结果集,然后执行两次替换:
String.prototype.trim = function(){
/**
* @param rs :匹配结果
* @param $1: 第 1 个 () 提取结果
* @param $2: 第 2 个 () 提取结果
* @param offset: 匹配开始位置
* @param source :原始字符串
*/
this.replace(/(^\s+)|(\s+$)/g,function(rs,$1,$2,offset,source){
//arguments 中的每个元素对应一个参数
console.log(arguments);
});
};
" abcd ".trim();
输出结果:
[" ", " ", undefined, 0, " abcd "] // 第 1 次匹配结果
[" ", undefined, " ", 5, " abcd "] // 第 2 次匹配结果
(2 )提取浏览器 url 中的参数名和参数值,生成一个 key/value 的对象
function getUrlParamObj(){
var obj = {};
// 获取 url 的参数部分
var params = window.location.search.substr(1);
//[^&=]+ 表示不含 & 或 = 的连续字符,加上 () 就是提取对应字符串
params.replace(/([^&=]+)=([^&=]*)/gi,function(rs,$1,$2){
obj[$1] = $2;
});
return obj;
/([&=]+)=([&=]*)/gi 每次匹配到的都是一个完整 key/value, 形如 xxxx=xxx, 每当匹配到一个这样的结果时就执行回调,并传递匹配到的 key 和 value ,对应到 $1 和 $2
(3 )在字符串指定位置插入新字符串
String.prototype.insetAt = function(str,offset){
// 使用 RegExp() 构造函数创建正则表达式
var regx = new RegExp("(.{"+offset+"})");
return this.replace(regx,"$1"+str);
};
"abcd".insetAt('xyz',2); // 在 b 和 c 之间插入 xyz
// 结果 "abxyzcd"英镑符号 https://www.gendan5.com/currency/GBP.html
当
offset=2
时,正则表达式为:
(^.{2}) .
表示除
\n
之外的任意字符,后面加
{2}
就是匹配以数字或字母组成的前两个连续字符,加
()
就会将匹配到的结果提取出来,然后通过
replace
将匹配到的结果替换为新的字符串,形如:结果
=
结果
+str
(4 ) 将手机号 12988886666 转化成 129 8888 6666
复制代码
function telFormat(tel){
tel = String(tel);
// 方式一
return tel.replace(/(\d{3})(\d{4})(\d{4})/,function (rs,$1,$2,$3){
return $1+" "+$2+" "+$3
});
// 方式二
return tel.replace(/(\d{3})(\d{4})(\d{4})/,"$1 $2 $3");
}
(\d{3}\d{4}\d{4}) 可以匹配完整的手机号,并分别提取前 3 位、 4-7 位和 8-11 位, "$1 $2 $3" 是在三个结果集中间加空格组成新的字符串,然后替换完整的手机号。
替换 XXYY---->YYXX
var str = "aabb";
var reg = /(\w)\1(\w)\2/g
console.log(str.replace(reg, "$2$2$1$1"));//bbaa
var str = "aabb";
var reg = /(\w)\1(\w)\2/g
console.log(str.replace(reg, function($, $1, $2) {//replace 的第二个参数也可以传进去一个函数,但是如果要用子表达式,那么就必须先传 $, 然后再传要用的子表达式。
return $2 + $2 + $1 + $1;// 子表达式用 $ 取的时候要用加号把它们连接起来
}));//bbaa
替换the-first-name-------->theFirstName
var reg = /-(\w)/g; // 因为要操作 f 和 n 让它们变成大写,所以要用子表达式的方式传递
var str = "the-first-name";
console.log(str.replace(reg, function($, $1){
return $1.toUpperCase();
}))
3, 字符串去重
var str = "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbccccccccccccc";
var reg = /(\w)\1*/g;
console.log(str.replace(reg, "$1"));// abc
4 ,实现从后往前每 3 个 0 打个小数点
var str = "10000000000";
var reg = /(?=(\B)(\d{3})+$)/g
// 从末尾开始,然后找 3 个数字连在一起的 (\d{3})+$ ,然后用 ?= 前面为空就表示正向预查空的地方,
// 最后添加 (\B) 是因为如果 0 的个数为偶数(假设 100000000000 ),那么就会出现 .100.000.000.000 这样的情况,所以就要加上非单词边界
console.log(str.replace(reg, "."));//10.000.000.000
exec() 方法
该方法是专门为捕获组而设计的,其接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;
在没有匹配项的情况下返回null 。返回的数组虽然是 Array 的实例,但是包含两个额外的属性: index 和 input
其中index 表示匹配项在字符串中的位置,而 input 表示应用字符串表达式的字符串。
var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;
var matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches.input); //mom and dad and baby
console.log(matches[0]); //mom and dad and baby
console.log(matches[1]); //and dad and baby
console.log(matches[2]); //and baby
对于exec() 方法而言,即使在模式中设置了全局标志 g ,它每次也只是返回一个匹配项。在不设置全局标志的情况下,在同一个字符串上多次调用 exec() 方法将始终返回第一个匹配项的信息。
而在设置全局标志的情况下,每次调用exec() 则都会在字符串中继续查找新匹配项,如下例子:
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;
var matches = pattern1.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern1.lastIndex); //0
matches = pattern1.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern1.lastIndex); //0
var pattern2 = /.at/g;
var matches = pattern2.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern2.lastIndex); //3
var matches = pattern2.exec(text);
console.log(matches.index); //5
console.log(matches[0]); //bat
console.log(pattern2.lastIndex); //8