Python 正则表达式实战指南:模式匹配与文本处理
正则表达式 是一种特殊字符序列,帮助你匹配或查找字符串,使用专用语法构建模式。正则表达式在 UNIX 世界广泛应用。
Python re 模块提供完整的 Perl 风格正则表达式支持。编译或使用正则表达式出错时抛出 re.error 异常。
我们将介绍两个核心函数处理正则表达式。首先,正则表达式中某些字符有特殊含义,为避免混淆,我们使用原始字符串 r'expression'。
match 函数
尝试将正则 pattern 与 string 的开头匹配,支持可选 flags。
语法
re.match(pattern, string, flags=0)
参数说明:
| 序号 | 参数及说明 |
|---|---|
| 1 | pattern:要匹配的正则表达式。 |
| 2 | string:被搜索字符串,匹配从字符串开头开始。 |
| 3 | flags:按位或(|)组合多个修饰符,详见下表。 |
re.match 成功返回 match 对象,失败返回 None。使用 match 对象的 group(num) 或 groups() 获取匹配内容。
| 序号 | Match 对象方法及说明 |
|---|---|
| 1 | group(num=0):返回整个匹配(或指定子组)。 |
| 2 | groups():返回所有匹配子组组成的元组(无则为空)。 |
示例
#!/usr/bin/python
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print("matchObj.group() : ", matchObj.group())
print("matchObj.group(1) : ", matchObj.group(1))
print("matchObj.group(2) : ", matchObj.group(2))
else:
print("No match!!")
输出:
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
search 函数
在 string 中搜索首次出现的正则 pattern,支持可选 flags。
语法
re.search(pattern, string, flags=0)
参数同 match,区别在于 search 匹配字符串任意位置。
返回 match 对象或 None,同样用 group() 和 groups() 提取。
示例
#!/usr/bin/python
import re
line = "Cats are smarter than dogs"
searchObj = re.search(r'(.*) are (.*?) .*', line, re.M|re.I)
if searchObj:
print("searchObj.group() : ", searchObj.group())
print("searchObj.group(1) : ", searchObj.group(1))
print("searchObj.group(2) : ", searchObj.group(2))
else:
print("Nothing found!!")
输出:
searchObj.group() : Cats are smarter than dogs
searchObj.group(1) : Cats
searchObj.group(2) : smarter
匹配与搜索的区别
Python 基于正则提供两种基本操作:match 仅检查字符串开头,search 检查字符串任意位置(Perl 默认行为)。
示例
#!/usr/bin/python
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'dogs', line, re.M|re.I)
if matchObj:
print("match --> matchObj.group() : ", matchObj.group())
else:
print("No match!!")
searchObj = re.search(r'dogs', line, re.M|re.I)
if searchObj:
print("search --> searchObj.group() : ", searchObj.group())
else:
print("Nothing found!!")
输出:
No match!!
search --> searchObj.group() : dogs
搜索与替换
re 模块最重要的方法之一是 sub。
语法
re.sub(pattern, repl, string, max=0)
将 string 中所有匹配 pattern 替换为 repl,除非指定 max。返回修改后的字符串。
示例
#!/usr/bin/python
import re
phone = "2004-959-559 # This is Phone Number"
# 删除 Python 风格注释
num = re.sub(r'#.*$', "", phone)
print("Phone Num : ", num)
# 移除非数字字符
num = re.sub(r'\D', "", phone)
print("Phone Num : ", num)
输出:
Phone Num : 2004-959-559
Phone Num : 2004959559
正则表达式修饰符:可选标志
正则字面量可包含可选修饰符控制匹配行为,以可选标志形式指定,可用异或(|)组合多个:
| 序号 | 修饰符及说明 |
|---|---|
| 1 | re.I:忽略大小写匹配。 |
| 2 | re.L:按当前区域设置解释单词(影响 \w \W \b \B)。 |
| 3 | re.M:$ 匹配行尾(非仅字符串尾),^ 匹配行首。 |
| 4 | re.S:点号匹配任意字符含换行符。 |
| 5 | re.U:按 Unicode 字符集解释字母(影响 \w \W \b \B)。 |
| 6 | re.X:允许“美观”正则语法,忽略空白(集合 [] 内或反斜杠转义外),将未转义 # 视为注释标记。 |
正则表达式模式
除控制字符 (+ ? . * ^ $ ( ) [ ] { } | \) 外,所有字符匹配自身。控制字符前加反斜杠转义。
Python 可用正则语法列表:
| 序号 | 模式及说明 |
|---|---|
| 1 | ^:匹配行首。 |
| 2 | $:匹配行尾。 |
| 3 | .:匹配除换行外任意单字符,m 选项允许匹配换行。 |
| 4 | [...]:匹配括号内任意单字符。 |
| 5 | [^...]:匹配不在括号内的任意单字符。 |
| 6 | re*:匹配前面表达式 0 次或多次。 |
| 7 | re+:匹配前面表达式 1 次或多次。 |
| 8 | re?:匹配前面表达式 0 次或 1 次。 |
| 9 | re{n}:精确匹配 n 次。 |
| 10 | re{n,}:匹配 n 次或更多。 |
| 11 | re{n,m}:匹配 n 到 m 次。 |
| 12 | a|b:匹配 a 或 b。 |
| 13 | (re):分组并记忆匹配文本。 |
| 14 | (?imx):在正则内临时开启 i/m/x 选项,括号内仅影响该区域。 |
| 15 | (?-imx):临时关闭 i/m/x 选项。 |
| 16 | (?:re):分组但不记忆匹配文本。 |
| 17 | (?imx:re):括号内临时开启 i/m/x。 |
| 18 | (?-imx:re):括号内临时关闭 i/m/x。 |
| 19 | (?#...):注释。 |
| 20 | (?=re):零宽正向先行断言,指定位置不消耗字符。 |
| 21 | (?!re):零宽负向先行断言。 |
| 22 | (?>re):独立匹配无回溯。 |
| 23 | \w:匹配单词字符。 |
| 24 | \W:匹配非单词字符。 |
| 25 | \s:匹配空白,等价 [\t\n\r\f]。 |
| 26 | \S:匹配非空白。 |
| 27 | \d:匹配数字,等价 [0-9]。 |
| 28 | \D:匹配非数字。 |
| 29 | \A:匹配字符串开头。 |
| 30 | \Z:匹配字符串结尾,若有换行则匹配换行前。 |
| 31 | \z:匹配字符串结尾。 |
| 32 | \G:匹配上次匹配结束位置。 |
| 33 | \b:括号外匹配单词边界,括号内匹配退格 (0x08)。 |
| 34 | \B:匹配非单词边界。 |
| 35 | \n, \t 等:匹配换行、回车、制表符等。 |
| 36 | \1...\9:匹配第 n 个分组子表达式。 |
| 37 | \10:若第 10 组已匹配则匹配该组,否则视为八进制字符码。 |
正则表达式示例
字面字符
| 序号 | 示例及说明 |
|---|---|
| 1 | python:匹配 "python"。 |
字符类
| 序号 | 示例及说明 |
|---|---|
| 1 | [Pp]ython:匹配 "Python" 或 "python"。 |
| 2 | rub[ye]:匹配 "ruby" 或 "rube"。 |
| 3 | [aeiou]:匹配任一小写元音。 |
| 4 | [0-9]:匹配任意数字,等价 [0123456789]。 |
| 5 | [a-z]:匹配任意小写 ASCII 字母。 |
| 6 | [A-Z]:匹配任意大写 ASCII 字母。 |
| 7 | [a-zA-Z0-9]:匹配以上任意字符。 |
| 8 | [^aeiou]:匹配非小写元音。 |
| 9 | [^0-9]:匹配非数字。 |
特殊字符类
| 序号 | 示例及说明 |
|---|---|
| 1 | .:匹配除换行外任意字符。 |
| 2 | \d:匹配数字 [0-9]。 |
| 3 | \D:匹配非数字 [^0-9]。 |
| 4 | \s:匹配空白 [ \t\r\n\f]。 |
| 5 | \S:匹配非空白 [^ \t\r\n\f]。 |
| 6 | \w:匹配单词字符 [A-Za-z0-9_]。 |
| 7 | \W:匹配非单词字符 [^A-Za-z0-9_]。 |
重复情况
| 序号 | 示例及说明 |
|---|---|
| 1 | ruby?:匹配 "rub" 或 "ruby"(y 可选)。 |
| 2 | ruby*:匹配 "rub" 加 0 个或多个 y。 |
| 3 | ruby+:匹配 "rub" 加 1 个或多个 y。 |
| 4 | \d{3}:精确匹配 3 位数字。 |
| 5 | \d{3,}:匹配 3 位或更多数字。 |
| 6 | \d{3,5}:匹配 3、4、5 位数字。 |
非贪婪重复
匹配最少重复次数:
| 序号 | 示例及说明 |
|---|---|
| 1 | <.*>:贪婪,匹配 " |
| 2 | <.*?>:非贪婪,在 " |
括号分组
| 序号 | 示例及说明 |
|---|---|
| 1 | \D\d+:无分组,+ 重复 \d。 |
| 2 | (\D\d)+:分组,+ 重复 \D\d 对。 |
| 3 | ([Pp]ython(, )?)+:匹配 "Python", "Python, python, python" 等。 |
反向引用
再次匹配之前匹配的分组:
| 序号 | 示例及说明 |
|---|---|
| 1 | ([Pp])ython&\1ails:匹配 "python&pails" 或 "Python&Pails"。 |
| 2 | (['"])[^\1]*\1:单/双引号字符串。\1 匹配第 1 组内容,\2 匹配第 2 组,以此类推。 |
备选分支
| 序号 | 示例及说明 |
|---|---|
| 1 | python|perl:匹配 "python" 或 "perl"。 |
| 2 | rub(y|le):匹配 "ruby" 或 "ruble"。 |
| 3 | Python(!+|\?):"Python" 后跟一个或多个 ! 或一个 ?。 |
锚点
指定匹配位置:
| 序号 | 示例及说明 |
|---|---|
| 1 | ^Python:匹配字符串或内部行开头的 "Python"。 |
| 2 | Python$:匹配字符串或行结尾的 "Python"。 |
| 3 | \APython:匹配字符串开头的 "Python"。 |
| 4 | Python\Z:匹配字符串结尾的 "Python"。 |
| 5 | \bPython\b:匹配单词边界的 "Python"。 |
| 6 | \brub\B:\B 非单词边界,匹配 "rube" 和 "ruby" 中的 "rub" 但不单独匹配。 |
| 7 | Python(?=!):后跟 ! 时匹配 "Python"。 |
| 8 | Python(?!\!):后不跟 ! 时匹配 "Python"。 |
括号特殊语法
| 序号 | 示例及说明 |
|---|---|
| 1 | R(?#comment):匹配 "R",其余为注释。 |
| 2 | R(?i)uby:匹配 "uby" 时忽略大小写。 |
| 3 | R(?i:uby):同上。 |
| 4 | rub(?:y|le):仅分组不创建 \1 反向引用。 |
Python
- C# 正则表达式完全指南:Regex 类、常用模式与实战示例
- 精通Python数据类型:实战指南
- 精通Python运算符:全面指南
- 精通Python Pass语句:实战指南
- 精通Python函数参数:位置、关键字与默认参数
- 精通 Python 字典:创建、操作与进阶技巧
- 精通 Python 迭代器:工作原理与自定义构建
- Python 闭包详解:嵌套函数如何捕获变量
- Python 正则表达式 (re 模块) 实战指南
- 精通 Python datetime:日期、时间与时区实战指南
- Python 语言概览:高级、可读、交互式与面向对象
- Java 正则表达式完全指南:掌握 java.util.regex 模式匹配