正则表达式总结
JyLie 2020-02-21 RegExp
正则表达式是匹配模式,要么匹配字符,要么匹配位置
# 前言
一次因肥炀同学问起正则表达式怎么搞,于是发布于公众号~
# 构建一个正则表达式
构建正则主要有两种方式:
- 正则表达式字面量:由包含在斜杠
/
之间的模式组成。- 匹配两个数字格式如:
/^\d{2}$/.test(88)
- 匹配两个数字格式如:
- 调用 RegExp 对象的构造函数
- 匹配两个数字格式如:
new RegExp("^\\d{2}$").test(88)
- 匹配两个数字格式如:
# 字符匹配
内容包括:
- 两种模糊匹配
- 字符组
- 量词
- 分支结构
- 案例分析
# 两种模糊匹配
- 横向模糊匹配
一个正则可匹配的字符串的长度不是固定的,可以是多种情况的
var regex = /ab{2,5}c/g;
var string = 'abc abbc abbbc abbbbc abbbbbc abbbbbbc';
console.log(string.match(regex));
// => ["abbc", "abbbc", "abbbbc", "abbbbbc"]
1
2
3
4
2
3
4
- 纵向模糊匹配
一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。
var regex = /a[123]b/g;
var string = 'a0b a1b a2b a3b a4b';
console.log(string.match(regex));
// => ["a1b", "a2b", "a3b"]
1
2
3
4
2
3
4
# 字符组 []
- 范围表示法:
如匹配“a”、“-”、“z”这三者中任意一个字符
可表示为:[-az]或[az-]或[a-z]
- 排除字符组
字符组的第一位放^(脱字符),表示求反的概念
如[^abc],表示是一个除"a"、"b"、"c"之外的任意一个字符
- 常见的简写形式
\d 就是[0-9]。表示是一位数字。记忆方式:其英文是 digit(数字)。
\D 就是[^0-9]。表示除数字外的任意字符。
\w 就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆>>w 是 word 的简写,也称单词字符。
\W 是[^0-9a-za-z_]。非单词字符。
\s 是[ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s 是 space character 的首字母。
\S 是[^ \t\v\n\r\f]。 非空白符。
. 就是[^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号...中的每个点,都可以理解成占位符,表示任何类似的东西。
[\u4e00-\u9fa5] 是中文字符集的 Unicode形式,表示匹配所有中文字符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上述正则模式都是匹配某一种类型的字符,如果想匹配所有字符,除了可以使用通配符.
外,还可以通过字符组形式来实现,如:[\d\D]、[\w\W]、[\s\S]和[^]
等都可以实现匹配任意字符。
# 量词
量词也称重复,用来匹配某字符、字符串出现的次数。通用格式为{m,n}
。
- 简写形式
{m,} 表示至少出现 m 次。
{m} 等价于{m,m},表示出现 m 次。
+ 等价于{1,},表示至少出现一次。类似追加的意思,得先有一个,然后才考虑追加。
* 等价于{0,},表示没有出现或出现多次。类似看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。
? 等价于{0,1},表示出现或者不出现。记忆方式:问号的意思表示,有吗? + 等价于{1,},表示出现至少一次。
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 贪婪匹配与惰性匹配
惰性匹配:尽可能少的匹配。记忆>>量词后面加个问号,问一问你知足了吗,你很贪婪吗?有几种常见形式:
- 通过在量词后面加个问号就能实现惰性匹配,因此所有惰性匹配情形如下:
{m,n}?
{m,}?
??
+?
*?
1
2
3
4
5
2
3
4
5
- 分支也属于惰性
贪婪匹配:会尽可能多的匹配 (只要在能力范围内,越多越好)。有几种常见形式:
- 不带任何修饰的量词
{m,n}
/*
惰性案例
*/
var regex = /\d{2,5}?/g;
var string = '123 1234 12345 123456';
console.log(string.match(regex));
// => ["12", "12", "34", "12", "34", "12", "34", "56"]
/*
贪婪案例
*/
var regex = /\d{2,5}/g;
var string = '123 1234 12345 123456';
console.log(string.match(regex));
// => ["123", "1234", "12345", "12345"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 多选分支
一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。
具体形式如下:(p1|p2|p3),其中 p1、p2 和 p3 是子模式,用|(管道符)分隔,表示其中任何之一
例如要匹配"good"和"nice"可以使用/good|nice/。测试如下:
var regex = /good|nice/g;
var string = 'good idea, nice try.';
console.log(string.match(regex));
// => ["good", "nice"]
1
2
3
4
2
3
4
但有个事实我们应该注意,比如我用/good|goodbye/,去匹配"goodbye"字符串时,结果是"good":
var regex = /good|goodbye/g;
var string = 'goodbye';
console.log(string.match(regex));
// => ["good"]
1
2
3
4
2
3
4
而把正则改成/goodbye|good/,结果是:
var regex = /goodbye|good/g;
var string = 'goodbye';
console.log(string.match(regex));
// => ["goodbye"]
1
2
3
4
2
3
4
也就是说,分支结构也是惰性的,即当前面的匹配上了,后面的就不再尝试了。