Python 详细模式写可读正则
可读模式(VERBOSE)让模式里的空白与井号注释被忽略,从而可以把一条长模式拆成多行书写,每行只表达一个逻辑单元并在行尾写注释。它对复杂模式的评审与维护帮助很大,代价是「空白被忽略」这条规则本身也会带来陷阱:需要匹配真实空格时必须显式转义或放进字符类。
基本信息
| 开启方式 | 传入 VERBOSE 标志,或在模式开头写内联标志,或对某个分组使用带冒号形式 |
|---|---|
| 被忽略的内容 | 未转义的空白字符与井号开始到行尾的注释 |
| 不被忽略的位置 | 字符类内部:方括号里的空白与井号都仍然是普通字符 |
| 书写建议 | 配合原始字符串与三引号,让每一行对应一个逻辑单元 |
典型使用场景
- 复杂校验规则:把 URL、日志格式等长模式分行书写,便于逐段评审
- 团队协作:模式由多人维护,注释说明每段语义能显著降低误改概率
- 教学与文档:把模式与解释放在一起,便于在文档中直接展示
- 调试定位:分行书写后可以按段注释掉,快速缩小问题范围
- 模式库建设:规则集中管理时统一使用可读模式提高整体可读性
可读模式写法
可读模式写法
import re
pat = re.compile(r'''
(?P<scheme> https? ) :// # 协议部分,允许 http 与 https
(?P<host> [^/:?#]+ ) # 主机名,遇分隔符即停
(?: : (?P<port> \d{1,5}) )? # 端口可选,位数限制在五位以内
(?P<path> /[^?#]* )? # 路径可选,不含问号与井号
''', re.X)
pat.fullmatch('https://example.com:8443/a') # 分行书写不影响匹配结果
re.search(r'(?x) a \s+ b', 'a b') # 内联形式:空白被忽略
re.search(r'(?x) [a b]', 'a') # 字符类内空格仍是字符本身语法与是否忽略空白
| 写法 | 空白处理 | 说明 |
|---|---|---|
| 模式中的普通空格 | 被忽略 | 匹配真实空格必须转义或放进字符类 |
| 井号 | 开启注释直到行尾 | 匹配字面井号需转义或放进字符类 |
| 方括号内部 | 不忽略 | 字符类里的空格与井号都是普通字符 |
| 转义后的空白 | 不忽略 | 用来精确匹配一个空格 |
| 局部标志分组 | 仅该分组内忽略 | 适合在长模式里局部使用 |
字符串拼接时要格外小心:注释会延伸到该行末尾,如果拼接点恰好在一行注释之后,后接的内容可能被当成注释的一部分吞掉,表现为「拼上去的条件完全没生效」。
可读模式不改变匹配语义,只改变书写形式;如果开启后发现匹配结果变了,通常是因为原本用于对齐的空白或井号此前是作为字面字符参与匹配的,此时需要把它们显式表达出来。