入门
元字符及其反义
元字符是正则表达式的基本元素。
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 28 29 30 31 32 33 34 35 36 37 38
| .
\w
\W
\s
\S
\d
\D
\b
\B
^
$
[^x]
[^aeiou]
\babc ^abc
^\d\d\d\d\d\d\d\d$
^1\d\d\d\d\d\d\d\d\d\d\d\d$
|
重复限定符
用来处理重复的元素,简化正则写法。
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
| *
+
?
{n}
{n,}
{n,m}
^\d{8}$
^1\d{10}$
^\d{14, 18}$
^ab*$
|
分组
用于同时限定多个元素。
转义
用于表示正则里占用的特殊字符。
条件或
1 2 3 4 5 6 7
| |
^(130|131|132|155|156|185|186|145|176)\d{8}$
|
区间
元素逐个枚举会比较复杂,所以用区间简化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| []
[0-9]
[A-Z]
[165af]
^((13[0-2])|(15[5-6])|(18[5-6])|145|176)$
|
进阶
零宽断言
零宽:不占位,断言:用于定位。
- 正向先行断言(正前瞻)
- 语法:
(?=pattern)
- 作用:匹配 pattern 表达式的前面内容,不返回本身。
- 正向后行断言(正后顾):
- 语法:
(?<=pattern)
- 作用:匹配 pattern 表达式的后面的内容,不返回本身。
- 负向先行断言(负前瞻)
- 语法:
(?!pattern)
- 作用:匹配非 pattern 表达式的前面内容,不返回本身。
- 负向后行断言(负后顾)
- 语法:
(?<!pattern)
- 作用:匹配非 pattern 表达式的后面内容,不返回本身。
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 28 29 30 31
| >>> import re
>>> line = "<span class=\"read-count\">阅读数:641</span>"
>>> value = re.search(r".+(?=</span>)", line) >>> print(value.group()) <span class="read-count">阅读数:641
>>> value = re.search(r"\d+(?=</span>)", line) >>> print(value.group()) 641
>>> value = re.search(r"(?<=<span class=\"read-count\">阅读数:)\d+", line) >>> print(value.group()) 641
>>> line = "我爱祖国,我是祖国的花朵"
>>> value = re.search(r"祖国(?!的花朵)", line) >>> print(value.group()) 祖国
>>> value = re.search(r"(?<!我爱)祖国", line) >>> print(value.group()) 祖国
|
捕获与非捕获
用于分组匹配。
- 数字编号捕获组
- 语法:
(exp)
- 解释:每个括号表示一个分组,第0个分组表示整个表达式。
- 命名编号捕获组
- 非捕获组
- 语法:
(?:exp)
- 解释:用于标记这个分组不需要捕获。
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 28
| >>> import re
>>> line = "020-85653333"
>>> value = re.search(r"(0\d{2})-(\d{8})", line) >>> print(value.group(0)) 020-85653333 >>> print(value.group(1)) 020 >>> print(value.group(2)) 85653333
>>> value = re.search(r"(?P<区号>0\d{2})-(?P<号码>\d{8})", line) >>> value <re.Match object; span=(0, 12), match='020-85653333'> >>> print(value.group('区号')) 020 >>> print(value.group('号码')) 85653333
>>> value = re.search(r"(?:0\d{2})-(\d{8})", line) >>> value.group(0) '020-85653333' >>> value.group(1) '85653333'
|
反向引用
「捕获与非捕获」会返回一个捕获组,这个分组既可以在正则外部进行引用,也可以在正则表达式内部进行引用,实现一些较为复杂的匹配。在正则表达式内部引用捕获组,称之为反向引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| >>> import re
>>> line = "aabbbbgbddesddfiid"
value = re.search(r"(\w)\1", line) >>> value.group(0) 'aa'
>>> pattern = re.compile(r"(\w)\1") >>> for value in re.finditer(pattern, line): ... print(value.group(0)) ... aa bb bb dd dd ii
|
贪婪和非贪婪
- 贪婪模式:当正则表达式中包含能接受重复的限定符时,匹配尽可能多的字符。即能多不会少。
- 非贪婪模式:当正则表示中包含能接受重复的限定符时,匹配尽可能少的字符。即能少不会多。
- 多个贪婪量词在一起时,会按深度优先原则,也就是从左到右,优先满足左边的贪婪量词,剩余再分配下一个量词匹配。
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
| *
+
?
{n}
{n,}
{n,m}
*?
+?
??
{n}?
{n,}?
{n,m}?
|
参考资料