正则表达式是经过专门编写的文本字符串,用来匹配字符串集合中符合该模式的所有字符串。
¶元字符
在正则表达式中,元字符有特殊的含义。正则表达式的元字符如下。如果需要匹配元字符,需要通过\转义。或者将元字符放在\Q和\E的中间,例如\Q^$\E匹配字符串^$。
| 元字符 | 名称 | 作用 |
|---|---|---|
| . | 句点 | 匹配任意字符 |
| ^ | 脱字符 | 行起始锚位符 |
| $ | 美元符 | 行结束锚位符 |
| * | 星号 | 匹配零次或多次的量词 |
| + | 加号 | 匹配一次或多次的量词 |
| ? | 问号 | 匹配零次或一次的量词 |
| | | 竖线符 | 选择操作(或) |
| ( | 左括号 | 分组起始 |
| ) | 右括号 | 分组结束 |
| { | 左花括号 | 量词或代码块起始 |
| } | 右花括号 | 量词或代码块结束 |
| [ | 左方括号 | 字符组起始 |
| ] | 右方括号 | 字符组结束 |
| \ | 反斜线 | 对字符转义 |
¶字符组
关键点:
[]表示字符组- 字符中间的
-表示范围- 注意
[0-9]和[-09]的区别
- 注意
- 开头的
^表示取反 - 字符组一定会消耗一个字符
- 字符组内部的元字符与字符组外部的元字符完全不一样
- 开头的
-和字符中间的-有特殊含义,其余字符均匹配自身
- 开头的
| 示例 | 说明 |
|---|---|
| [12] | 匹配字符1或2。 |
| [^12] | 不匹配字符1和2 |
| [0-9] | 匹配数字字符 |
| [a-z] | 匹配小写字母 |
常用字符组缩写
| 字符组缩写 | 字符组 | 说明 |
|---|---|---|
| \d | [0-9] | 数字字符 |
| \D | [^0-9] | 非数字字符 |
| \s | [ \t\n\r] | 空白符 |
| \S | [^ \t\n\r] | 非空白符 |
| \w | [_a-zA-Z0-9] | 单词字符 |
| \W | [^_a-zA-Z0-9] | 非单词字符 |
| . | [^\n\r] | 除行结束符之外的所有字符 |
POSIX字符组
| 字符组 | 描述 |
|---|---|
[[:alnum:]] |
匹配字母及数字 |
[[:alpha:]] |
匹配字母 |
[[:ascii:]] |
匹配ASCII 字符(共128 个) |
[[:blank:]] |
匹配空白字符 |
[[:ctrl:]] |
匹配控制字符 |
[[:digit:]] |
匹配数字 |
[[:graph:]] |
匹配图形字符 |
[[:lower:]] |
匹配小写字母 |
[[:print:]] |
匹配可打印字符 |
[[:punct:]] |
匹配标点符号 |
[[:space:]] |
匹配空格字符 |
[[:upper:]] |
匹配大写字母 |
[[:word:]] |
匹配单词字符 |
[[:xdigit:]] |
匹配十六进制数字 |
¶捕获分组与后向引用
使用()对正则表达式匹配的字符进行分组,分组不会改变正则表达式的匹配。使用\1或$1对分组进行引用。\1表示第一个开括号(的分组,\2表示第二个开括号的分组。
例如正则表达式(\d)\d\1匹配字符串575。第一个\d匹配字符5并加入分组,\1对分组进行引用。
(?:)表示分组但是不引用,这会提高正则表达式的性能。
¶量词
例如正则表达式:a?。量词?修饰前面的a,表示字符a出现0次或1次。量词也可以用{min,max}表达。
| 量词 | 说明 |
|---|---|
| ? | 0或1次,{0,1} |
| + | 1或无穷次,{1,} |
| * | 0或无穷次,{0,} |
| {n} | n次 |
| {n,m} | 最少n次,最多m次 |
| {n,} | 最少n次 |
量词默认使用贪心原则,即尽可能匹配更多的内容。量词首先尝试匹配整个字符串,如果失败则回退一个字符后再次尝试。
懒惰是另一种策略,它从目标的起始位置开始尝试寻找匹配,每次检查字符串的一个字符,寻找它要匹配的内容。最后,它会尝试匹配整个字符串。要使用懒惰量词,需要在普通量词后添加?。
占有量词会覆盖整个目标然后尝试寻找匹配内容,但只尝试一次,不会回溯。需要在普通量词后添加+。
¶选择
竖线符|表示选择,从多个表达式中选择一个匹配。例如a|ab表示匹配字符a或字符串ab。注意选择和字符数组的区别,字符数组一次只能匹配一个字符,选择根据情况可以匹配多个字符。
可以借助分组,为选择确定一个明确的边界。例如表达式a|bcd和(a|bc)d的区别。
¶锚位符
锚位符用来匹配位置,不消耗任何字符。
| 锚位符 | 说明 |
|---|---|
| ^ | 行起始位置 |
| $ | 行结束位置 |
| \b | 单词边界 |
| \B | 非单词边界 |
\< |
单词开头。旧语法,可能不支持 |
\> |
单词结尾。旧语法,可能不支持 |
| \A | 主题词的开始 |
| \Z | 主题词的结尾 |
¶环视
环视是一种非捕获分组,根据某个模式之前或之后的内容匹配其他模式。环视不匹配任何字符,只匹配文本中的特定位置。环视不会占用字符。
| 环视 | 正则表达式 | 说明 |
|---|---|---|
| 肯定顺序环视 | (?=…) | 子表达式能够匹配右侧文本 |
| 否定顺序环视 | (?!..) | 子表达式不能匹配右侧文本 |
| 肯定逆序环视 | (?<=…) | 子表达式能够匹配左侧文本 |
| 否定逆序环视 | (?<!..) | 子表达式不能够匹配左侧文本 |
考虑字符串see Jeffs book,正则表达式(?=s\b)匹配f和s中间的位置,因为这个位置右侧包含字符串s\b。
考虑任意一个位置,如果对右边的字符有要求,可以使用肯定顺序环视(枚举)或否定逆序环视(排除)。
1 | (?=s\b) # 只能匹配 f 和 s 中间的位置 |
如果对左边的字符有要求,可以使用肯定逆序环视(枚举)或否定顺序环视(排除)。
¶学习资料
- 学习正则表达式,Michael Fitzgerald
- https://book.douban.com/subject/22601258/
- 内容比较简单,适合零基础入门
- 精通正则表达式(第三版),Jeffrey E.F.Friedl
- https://book.douban.com/subject/11589967/
- 内容比较深入,适合进阶学习
- 电子版PDF
¶Python使用正则表达式
参考:https://docs.python.org/zh-cn/3/library/re.html
1 | import re |