概要
正则主要应用在两个地方:
- 字符串的方法可以使用正则的有:match()、replace()、search()、split()
- 正则的方法有:exec()、test()
match 和 exec
var str = "1a24a5qwerasadf";
var reg = /a/;
var result1 = str.match(reg);
var result2 = reg.exec(str);
console.log(result1);
console.log(result2);
// [ 'a', index: 8, input: '1245qwerasdf', groups: undefined ]
// [ 'a', index: 8, input: '1245qwerasdf', groups: undefined ]
//如果未正确匹配结果exec和match都会返回null
在正则不加g
的情况下,两个方法匹配的结果是相同的。返回首次匹配成功的类数组对象。
var str = "1a24a5qwerasadf";
var reg = /a/g;//全局匹配
var result1 = str.match(reg);
var result2 = reg.exec(str);
console.log(result1);
console.log(result2);
// [ 'a', 'a', 'a', 'a' ]
// [ 'a', index: 1, input: '1a24a5qwerasadf', groups: undefined ]
g
对 exec
没有效果,对 match 有效果,match 会返回所有匹配成功结果的数组。但是 exec 依然可以通过代码来达到 match 的效果。我们来研究下:
var str = "AaBbCcDd";
var reg = /[a-z]/g;
var result = reg.exec(str);
//[ 'a', index: 1, input: 'AaBbCcDd', groups: undefined ]
console.log(result);
var result = reg.exec(str);
会返回类数组对象,但是exec的执行可以叠加。一直叠加到最后一个结果返回 null,在重新开始。结果就像下面的代码:
var str = "AaBbCcDd";
var reg = /[a-z]/g;
var result = reg.exec(str);//[ 'a', index: 1, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'b', index: 3, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'c', index: 5, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'd', index: 7, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//null
var result = reg.exec(str);//[ 'a', index: 1, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'b', index: 3, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'c', index: 5, input: 'AaBbCcDd', groups: undefined ]
var result = reg.exec(str);//[ 'd', index: 7, input: 'AaBbCcDd', groups: undefined
var result = reg.exec(str);//null
// 无限循环
console.log(result);//null
这种写法太low了,我们使用 while 改写下:
var str = "AaBbCcDd";
var reg = /[a-z]/g;
var result = [];
while(reg.exec(str) !== null){//执行了一次exec
result.push(reg.exec(str)[0]);//又执行了一次exec
};
console.log(result);
//[ 'b', 'd' ]
上面的结果返回的数组为什么少了两个元素。没错一个 while 循环我们执行了两次 exec。现在改写成执行一次的:
var str = "AaBbCcDd";
var reg = /[a-z]/g;
var result = [];
var res;
while((res = reg.exec(str)) !== null){//括号注意
result.push(res[0]);
};
console.log(result);
//[ 'a', 'b', 'c', 'd' ]
match 中的分组捕获:
var phone = "110-110-999-213-222-987-987-776-010-345-456-198";
var reg = /(\d{3})\-\1/g;
var result = phone.match(reg);
console.log(result);
//[ '110-110', '987-987' ]
\1
代表与分组1(第一个括号)中一样的内容,\2
代表与分组2(第二个括号)中一样的内容。常用于寻找相同子串,例如:
var str = "ABCCCCBBBWWWvdfWEEsfsEIIIOOOOOQJALSJJDCCNQQOIWJJDONDQDQ";
var reg = /(\w)\1+/g;
var result = str.match(reg);
console.log(result);
// [
// 'CCCC', 'BBB',
// 'WWW', 'EE',
// 'III', 'OOOOO',
// 'JJ', 'CC',
// 'QQ', 'JJ'
// ]
search
var str = "ABChioejfi23948178341QDQ";
var reg = /[a-z]/g;
var index = str.search(reg);
console.log(index);//3
返回第一个匹配成功字符串的下标,g
无任何作用。 search 还可以用 indexOf 来替代,比如上述结果可以更改为:
console.log(str.indexOf("i"));
search 就像用了正则的 indexOf 。例外 indexOf 和 search 没有成功匹配到结果会返回 -1
,常用于字符串去重。
replace
- 字符串形式的替换
var str = "爱情公寓中成果是一个00后,成果也是张伟的女朋友";
var reg = /成果/g;
const result = str.replace(reg,"诸葛大力");
console.log(result);
- 函数形式的替换
var str = "爱情公寓中成果是一个00后,成果也是张伟的女朋友";
var reg = /成果/;
const result = str.replace(reg,function(a,b,c){
// a:被替换的元素;b:索引; c:原字符串
console.log(a)
console.log(b)
console.log(c)
//return 的值就是要替换的值
return "诸葛大力";
});
console.log(result);
// 成果
// 5
// 爱情公寓中成果是一个00后,成果也是张伟的女朋友
// 爱情公寓中诸葛大力是一个00后,成果也是张伟的女朋友
replace 中使用分组:
- 字符串形式的分组捕获
姓名交换是最简单的一个:
var str = "Tom David";
var reg = /(\w+)\s+(\w+)/g;
const result = str.replace(reg,"$2 $1");
console.log(result);
//David Tom
$1
代表与分组1中一样的内容,$2
代表与分组2中一样的内容。
- 函数形式的分组捕获
回调函数中可以接收分组捕获的内容,在 match 参数之后,$1 参数表示第一个捕获的内容,依次类推,不限制数量。
var str = "Tom David";
var reg = /(\w+)\s+(\w+)/g;
const result = str.replace(reg,function(match,$1,$2,index,str){
console.log(match);
console.log(index);
console.log($1);
console.log($2);
console.log(str);
return $2 + " " + $1;
});
console.log(result);
// Tom David
// 0
// Tom
// David
// Tom David
// David Tom
练习:
请把字符串
"爱情公寓中:★louyixiao★饰演胡一菲,★lijiahang★饰演张伟,★sunyizhou★饰演吕子乔,★lijinming★饰演陈美嘉,★chengguo★饰演诸葛大力。"
转换成以下格式:
爱情公寓中:娄艺潇饰演胡一菲,李佳航饰演张伟,孙艺洲饰演吕子乔,李金铭饰演陈美嘉,成果饰演诸葛大力。
答案如下:
var nameObj = {
louyixiao:"娄艺潇",
lijiahang:"李佳航",
sunyizhou:"孙艺洲",
lijinming:"李金铭",
chengguo:"成果"
};
var str = "爱情公寓中:★louyixiao★饰演胡一菲,★lijiahang★饰演张伟,★sunyizhou★饰演吕子乔,★lijinming★饰演陈美嘉,★chengguo★饰演诸葛大力。"
var reg = /★(\w+)★/g;
const result = str.replace(reg,function(match,$1,index,str){
return nameObj[$1];
});
console.log(result);
是不是有点 mustache 语法的感觉。。。
split 字符串转数组
//根据空格切割字符串
var arr = '大力 羽墨 美嘉 吕嘉一 婉瑜'.split(/\s+/);
console.log(arr);//[ '大力', '羽墨', '美嘉', '吕嘉一', '婉瑜' ]
test
结果返回 true or false,常用于表单验证。
var str = "爱情公寓三新人诸葛大力赵海棠咖喱酱";
var reg = /大力/;
if(reg.test(str)){//true
console.log(true);
}else{
console.log(false);
}
写作日期 2020年2月23日 01点12分
网友评论