0%

javascript-regex-match

javascript-regex-match

先提醒一下,虽然标题有regex,但是match在js中是字符串的方法,而不是正则表达式的方法。

match用來返回符合正则表达式的字符串,如果没有找到匹配的字符串则返回null

先看一个例子:

1
2
3
const str = "There are 3 dogs, 5 cats, 2 birds and 1 cow";
const matches = str.match(/\d/);
console.log(matches[0]); // 3, 返回第一个匹配。

match的返回值

match的返回值比较特殊,分以下几种情况,

  • 如果没有找到匹配,返回null
  • 如果找到了匹配,返回一个数组。

返回数组时,又分为以下几种情况

  1. 如果正则表达式没有g标志(且未分组),返回一个数组,看如下代码。
1
2
3
const str = "There are 3 dogs, 5 cats, 2 birds and 1 cow";
const matches = str.match(/\d/);
console.log(matches);

返回值如下:

1
2
3
4
5
6
[
'3', // 匹配的整个字符串
index: 10, // 匹配值对应的下标
input: 'There are 3 dogs, 5 cats, 2 birds and 1 cow', // 原始字符串
groups: undefined // 分组匹配的值
]

此时,你需要的匹配值是matches[0]

  1. 如果正则表达式没有g标志(且分组),返回一个数组,比之上面的返回值,多一个分组对应的值。
1
2
3
const str = "There are 3 dogs, 5 cats, 2 birds and 1 cow";
const matches = str.match(/(\d) cats/);
console.log(matches);

返回值如下:

1
2
3
4
5
6
7
8
[
'5 cats', // 匹配的整个字符串
'5', // 第一个分组匹配的值
index: 18, // 匹配值对应的下标
input: 'There are 3 dogs, 5 cats, 2 birds and 1 cow', // 原始字符串
groups: undefined // 分组匹配的值
]

此时,你需要的匹配值是matches[1]。(既然分组了,就要用分组的值呀,否则还分组干嘛呢?)

  1. 如果正则表达式有g标志(无论是否分组),返回一个数组,数组中的元素是所有匹配的值。
1
2
3
const str = "There are 3 dogs, 5 cats, 2 birds and 1 cow";
const matches = str.match(/\d/g); // 或者 str.match(/(\d)/g);
console.log(matches);

返回值如下:

1
[ '3', '5', '2', '1' ]

matchAll

match方法使用/g标记时,只能返回匹配的字符串,而无法返回分组信息,这时可以使用matchAll方法。

matchAll方法返回一个迭代器,而不是数组,所以不能直接输出,可以使用for...of循环遍历匹配的所有结果。

1
2
3
4
5
const str = "There are 3 dogs, 5 cats, 2 birds and 1 cow";
const matches = str.matchAll(/(\d) (cats|dogs)/g);
for (const match of matches) {
console.log(match);
}

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[
'3 dogs', // 匹配的整个字符串
'3', // 第一个分组匹配的值
'dogs', // 第二个分组匹配的值
index: 10, // 匹配值对应的下标
input: 'There are 3 dogs, 5 cats, 2 birds and 1 cow', // 原始字符串
groups: undefined // 分组匹配的值
]
[
'5 cats', // 匹配的整个字符串
'5', // 第一个分组匹配的值
'cats', // 第二个分组匹配的值
index: 18, // 匹配值对应的下标
input: 'There are 3 dogs, 5 cats, 2 birds and 1 cow', // 原始字符串
groups: undefined // 分组匹配的值
]

假设有如下需求,将There are 3 dogs, 5 cats, 2 birds and 1 cow这句话中每种动物及其数量提出出来,放到一个对象中,可以使用matchAll方法。

1
2
3
4
5
6
7
const str = 'There are 3 dogs, 5 cats, 2 birds and 1 cow';
const matches = str.matchAll(/(\d+) (cat|dog|bird|cow)/g);
const result = {};
for (const match of matches) {
result[match[2]] = match[1];
}
console.log(result);

输出如下:

1
{ dog: '3', cat: '5', bird: '2', cow: '1' }

整个需求如果要使用match方法来做,还是比较复杂的。

总结

什么时候用test, 什么时候用match

  1. 如果你只是想判断字符串是否满足某个规则,用test
  2. 如果你想要得到匹配的子串,用match
  3. 简单的字符串包含操作可以直接使用indexOfincludes等方法。