最近又用到了正则啦,发现匹配相同东西的时候,我和同事用不同的方法都可以,这里特意来归纳一下。
RegExp对象方法
test()
字符串的test
方法,比较常用在判断语句中,用于检测一个字符串是否匹配某个模式:
1 | RegExpObject.test(string) |
如果字符串 string 中含有与 RegExpObject 匹配的文本,则返回 true,否则返回 false:1
/\d/.test('asdf2') // --true 检测字符串`'asdf2'`中是否函数数字
exec()
exec()方法功能非常强大,它是一个通用的方法,用于比较复杂的模式匹配或者是你为你提供更多的信息:
1 | RegExpObject.exec(string) |
如果在string中找到了匹配的文本,则返回一个包含这些文本的数组,否侧返回null。这里有几个注意的地方:
返回的数组的第一个元素是与整个正则匹配的文本
然后数组的第二个元素是与整个正则的第一个子表达式(分组)相匹配的文本
数组的第三个元素整个正则的第二个子表达式(分组)相匹配的文本,以此类推。
1
2
3
4
5
6
7var result = /(\d+)-(\w+)/.exec('12-ab');
console.log(result) // --> ["12-ab", "12", "ab", index: 0, input: "12-ab"]
//exec() 都会把完整的细节添加到它返回的数组中,这里的细节指的就是index和input
整个正则表达式匹配的文本:`"12-ab"`
第一个子表达式匹配的文本:`"12"`
第二个子表达式匹配的文本:`"ab"`从上面返回的数组结果可知,数组添加了两个额外的属性,分别是:index, input
index: 匹配文本的第一个字符的位置.
input: 顾名思义,就是指输入的整体的文本了.1
2console.log(result.index) // --> 0
console.log(result.input) // --> '12-ab'执行exec函数时,尽管是全局匹配的正则表达式,但是exec方法只对指定的字符串进行一次匹配,
获取字符串中第一个与正则表达式想匹配的内容,并且将匹配内容和子匹配的结果存储到返回的数组中,
例如:
/\d/g.exec('a22')
,返回的结果和上面的结果一样:["2"]
1
/\d/g.exec('a22') // -->["2"]
深入了解 exec()
深入前看看RegExp的实例有哪些属性:
global
布尔,表示是否设置了 g 标志ignoreCase
布尔,表示是否设置了 i 标志lastIndex
搜索下一个匹配项时开始的位置,从0开始multiline
布尔值,表示是否设置了 m 标志source
正则表达式的字符串表示
例1:非全局匹配
1 | var reg = /\d/; |
结论:
同一正则表达式,在非全局匹配模式下,每次实例的lastIndex属性的值总是不变的(为第一次找到匹配文本所在的位置,上面为0 );
每次的匹配查找都是将lastIndex作为起始位置的
例2:全局匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28var reg = /\d/g;
//第一次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//输出
["1"]
2
第二次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//输出
["2"]
3
第三次匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//输出
["3"]
4
第四匹配
console.log(reg.exec('a123'));
console.log(reg.lastIndex);
//输出
null
0
结论:
同一正则表达式,在全局匹配模式下,每次实例的lastIndex属性的值为匹配文本最后一个字符的下一个位置,上面例子中第一次匹配的时候最后一个字符位置为1,则下一个位置为:2
当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
那当要获取全局匹配的全部匹配项时,可以通过循环来获取:1
2
3
4
5
6
7var reg = /\d/g,
result = [],
crt;
while((crt = reg.exec('a123')) !== null){
result = result.concat(crt)
};
result; //["1", "2", "3"]
String对象方法
match()
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。和exec()有些相似:
例1:非全局匹配
1 | var a = 'aaaa'.match(/\w/); |
可以看到,和exec()一样,在数组中返回了index 和 input属性。
或者是这样,match返回分组
例2:全局匹配
1 | var a = 'aaaa'.match(/\w/g); |
全局匹配就和exec方法有很大的不同了,他直接返回了所有符合匹配的子字符串的数组,另外,index和input属性也不在其中了,所以这个方法效率可能会高一些,但是如果你需要更多的信息,则用exec()吧
match函数在满足如下条件能实现和exec一样的功能:
1. 正则表达式中含有分组(括号)
2. 返回唯一的匹配
replace()
这也是一个比较灵活常用的方法,它用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
这个方法接收两个必须的参数:
pattern
: 这个参数可以是字符串或是RegExp对象replacement
: 替换匹配项的字符串或处理函数的返回值
返回结果:
当未找到匹配项的时候,返回原始字符串。1
2
3
4
5
6'aaaa'.replace('bbb', 'b') //"aaaa"
```
当`pattern`为字符串或者为非全局的RegExp对象的时候,只替换找到的第一项匹配项。
```javascript
'aaaa'.replace('a', 'b') //"baaa"
'aaaa'.replace(/\w/, 'b') //"baaa"
当pattern
为全局的RegExp对象的时候,替换每一项匹配项。1
'aaaa'.replace(/\w/g, 'b') //"bbbb"
replacement
:为函数时:1
2
3
4
5
6
7'aaaa'.replace(/\w/g, function() {
return 'b';
}); // "bbbb"
'aaaa'.replace(/\w/g, function(value) {
return value.toUpperCase();
}); // "AAAA"
结论:
函数的返回值将作为替换字符串
函数的第一个参数的值是每一个匹配项,当然还有第二个参数,它的值是每个匹配项在原始字符串的中位置,从0开始
特殊的 $:
replacement 中的 $ 字符具有特定的含义。如下表所示,它说明从模式匹配得到的字符串将用于替换。
字符 | 替换文本 |
---|---|
1、2、…、$99 | 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本 |
$& | 与 regexp 相匹配的子串 |
$` | 位于匹配子串左侧的文本 |
$’ | 位于匹配子串右侧的文本 |
$$ | 直接量符号 |
1 |
|