正则表达式是匹配模式,要么匹配字符,要么匹配位置。能够实现模糊匹配。
- 横向模糊匹配:正则可匹配的字符串的长度是不固定的
- 纵向模糊匹配:正则匹配的字符串,具体到某一位数字时,他可以不是某个确定的字符,可以用多种可能。
匹配字符
字符组
量词
匹配位置
符号 | 含义 |
---|---|
^ | 匹配开头,在多行匹配中匹配行开头 |
$ | 匹配结尾,在多行匹配中匹配行结尾 |
\b | \b 是单词边界, 具体就是 \w 与 \W 之间的位置, 也包括 \w 与 ^ 之间的位置, 和 \w 与 $ 之间的位置。 |
\B | \B 就是 \b 的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉 \b,剩下的都是 \B 的。 |
(?=p) | (?=p), p 是子模式,即 p 前面的位置 |
(?! p) | 与 (?=p) 相反,即非 p 前面的位置 |
(?<=p) | 只有在 p 后面才匹配 |
(?<! p) | 匹配非 p 后面位置,和上面相反 |
括号
括号提供子表达式,强调括号内的正则是一个整体。
- 分组
- 分支结构
分组引用
分组引用比普通模式多了分组编号, #1 #2 #3
![[Pasted image 20221125073625.png]]
提取数据、替换
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) );
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]
反向引用
可以在正则本身里引用分组,但只能引用之前出现的分组,即反向引用。
反向引用实际开发中因为对正则掌握不全面,很少使用,需要重视。
匹配 2022-11-25
字符,可以使用
var reg = \d{4}(-)\d{2}(-)\d{2}\
![[Pasted image 20221125075148.png]]
也可以使用反向引用。注意下面的正则中的 \1
,是分组引用,后面第二个 -
就可以使用分组引用的 \
去实现。
var reg = \d{4}(-)\d{2}\1\d{2}\
![[Pasted image 20221125074823.png]]
回溯
回溯和算法中的回溯非常像,都是先占有,然后等后面的匹配出现问题了,再回退,重新匹配。
正则 /ab{1,3}c/
,匹配文本 abbbc
,形式如下:
![[Pasted image 20221125080009.png]]
先匹配 3 个 b,然后匹配 c,这里一次性通过了,没有产生回溯。
如果匹配字符串 abbc
, 那么将产生回溯
![[Pasted image 20221125080132.png]]
他会持续性的匹配 b 字符,知道出错,然后产生回退(回溯)。
回溯形式
贪婪量词
在局部是贪婪地,但是也要满足整体的正确匹配。
惰性量词
惰性量词就是在贪婪量词后面加个问号,表示尽可能少的匹配。
var string = "12345";
var regex = /(\d{1,3}?)(\d{1,3})/;
console.log( string.match(regex) );
// => ["1234", "1", "234", index: 0, input: "12345"]
![[Pasted image 20221125081204.png]]
惰性量词,匹配到第一次就结束,但是为了整体匹配达成,需要进行多次匹配。因此最后 {1,3}?
的匹配是 12
var string = "12345";
var regex = /(\d{1,3}?)(\d{1,3}$)/;
console.log( string.match(regex) );
// => ['12345', '12', '345', index: 0, input: '12345', groups: undefined]
![[Pasted image 20221125081303.png]]
分支结构
分支结构也是惰性的,比如 /can|candy/
,匹配字符串 candy
,得到的结果是 can
,前面的分支满足了,就不会尝试后面的匹配。
语言本身
语言结构
结构 | 说明 |
---|---|
字面量 | 匹配一个具体字符,包括不用转义的和需要转义的。比如 a 匹配字符 “a”, 又比如 \n 匹配换行符,又比如 . 匹配小数点 |
字符组 | 匹配一个字符, 可以是多种可能之一, 比如 [0-9], 表示匹配一个数字。也有 \d 的简写形式。另外还有反义字符组,表示可以是除了特定字符之外任何一个字符,比如 [^0-9], 表示一个非数字字符,也有 \D 的简写形式 |
量词 | 表示一个字符连续出现, 比如 a{1, 3} 表示 “a” 字符连续出现 3 次。另外还有常见的简写形式, 比如 a+ 表示 “a” 字符连续出现至少一次 |
锚 | 匹配一个位置,而不是字符。比如 ^ 匹配字符串的开头,又比如 \b 匹配单词边界, 又比如 (?=\d) 表示数字前面的位置 |
分组 | 用括号表示一个整体,比如 (ab)+,表示 “ab” 两个字符连续出现多次, 也可以使用非捕获分组 (?:ab)+。 |
分支 | 多个子表达式多选一, 比如 abc|bcd, 表达式匹配 “abc” 或者 “bcd” 字符子串。反向引用, 比如 \2, 表示引用第 2 个分组 |
操作符优先级
操作符描述 | 操作符 | 优先级 |
---|---|---|
转义符 | \ | 1 |
括号和方括号 | ()、(?:…)、(?=…)、(?!…)、[…] | 2 |
量词限定符 | {m}、{m, n}、{m,}、?、*、+ |
3 |
位置和序列 | ^、$、元字符、一般字符 | 4 |
管道符 | | | 5 |
晚上想发布的时候,好像还是很难记,送上打油诗一首:
尖尖是开头,美国有末日
加加叠叠叠,星星可多少
问号最神秘,最多给一次
括号分类型,分组还给你
中括号最花心,一个即是对
花括号最贪心,总想多又多
花括号加问号,才懂够用就好
配上字符之后即是:
尖尖 (^^) 是开头,美国 ( $$) 有末日
加加(++)叠叠叠,星星 (**) 可多可少
问号 (??) 最神秘,最多给一次
括号 () 分类型,物以群分
中括号 [] 最花心,一个即是对
花括号 {m,n} 最贪心,总想多又多
花括号配问号{m,n}?,才懂够用够用就好
参考
- 正则指引
- JavaScript 正则表达式迷你书