让模式能排版
自由间距模式会忽略模式中的空白字符,并把井号到行尾的内容当作注释。于是长模式可以分段落、加缩进、写说明,像读一段代码那样读模式,而不是面对一整行符号。
两处例外要记住
字符类内部的空白不会被忽略,因为在类里空白往往就是被匹配的对象;想匹配空格本身则要写成转义或明确的字符类。井号在类内同样是普通字符,在类外才开始注释。
基本信息
| 开启方式 | 内联修饰符或对应语言的编译选项 |
|---|---|
| 忽略内容 | 模式中的空白字符与井号起始的注释 |
| 不忽略的位置 | 字符类内部的空白与符号 |
| 空格匹配 | 需要转义写法或显式字符类 |
| 多行书写 | 借助语言的多行字符串语法分行排版 |
| JS 现状 | 标准正则没有该标志,需用字符串拼接与换行注释代替 |
典型使用场景
- 书写并维护邮箱、日期、URL 这类长而复杂的模式
- 给模式各段落加注释,说明每段在匹配什么
- 团队评审模式时提高可读性,减少理解成本
- 把从文档抄来的紧凑模式改写成带注释版本
- 排查长模式某一段为何不生效,分段注释后逐段验证
带注释的模式写法
带注释的模式写法
import re
pat = r'''(?x)
\A # 整串开始
(?P<user>[A-Za-z0-9._%+-]+) # 用户名部分
@ # 分隔符
(?P<domain>[A-Za-z0-9.-]+) # 域名部分
\.[A-Za-z]{2,} # 顶级域
\Z # 整串结束
'''
re.fullmatch(pat, 'ok@example.com') # 排版不影响匹配语义
re.search(r'(?x)a\ b', 'a b') # 需要匹配空格时用转义写法
re.search(r'(?x)[a b]+', 'a b') # 也可用显式字符类包含空格忽略与保留对照
| 内容 | 类外 | 类内 |
|---|---|---|
| 空格与缩进 | 忽略 | 保留,参与匹配 |
| 制表符 | 忽略 | 保留,参与匹配 |
| 井号 | 开始注释,到行尾忽略 | 普通字符 |
| 换行 | 忽略 | 保留 |
| 转义空格 | 匹配一个空格 | 匹配一个空格 |
带注释的模式要在评审与复制之间做取舍:注释让维护更容易,但把模式复制到其他工具时注释会一起被带走,可能造成误解。交付时保留一份紧凑版本更稳妥。
开启自由间距后,模式里原本用来提高可读性的空格会被忽略,但也可能把有意为之的空格一起忽略。写完务必用真实样本验证,重点检查需要匹配空格的位置。