类内规则不一样
方括号内部有一套独立的解析规则:多数在类外有特殊含义的符号在类内退化为普通字符,真正保留特殊作用的只有反斜杠、位置敏感的脱字符与连字符、以及右中括号。写类时按类内规则判断,不能套用类外的直觉。
位置决定含义
类内有两个符号靠位置决定含义:脱字符写在首位表示取反,写在别处就是普通字符;连字符在两端或转义后表示本身,在中间表示区间。右中括号必须放在首位或转义,否则会提前结束整个类。
基本信息
| 退化为普通字符 | 点号、星号、加号、问号、圆括号、花括号、竖线、美元符号 |
|---|---|
| 仍保持特殊 | 反斜杠、位置敏感的脱字符与连字符、右中括号 |
| 简写仍有效 | 数字、单词、空白三类简写在类内照常生效 |
| 量词不生效 | 星号与加号在类内是普通字符,不起重复作用 |
| 易混点 | 反斜杠小写 b 在类内表示退格字符,而不是单词边界 |
| 引擎差异 | 部分构造在类内的行为按引擎而异,涉及边界情况以官方文档为准 |
典型使用场景
- 把一批标点整体列入白名单或黑名单,无需逐个转义
- 清洗文本时排除括号、引号、运算符等符号
- 匹配代码片段里的字面符号,避免逐字符加反斜杠
- 处理分隔符集合,例如把逗号、分号、竖线统一视为分隔
- 排查模式为什么报语法错误:先检查右中括号与连字符位置
类内写法的正误对比
类内写法的正误对比
import re
re.findall(r'[.*+?()]', 'a.*b+c') # 类内这些符号都是字面量,无需转义
re.findall(r'[\\]', 'a\\b') # 反斜杠本身在类内仍要转义
re.search(r'[]]', 'x]') # 右中括号放首位表示它本身
re.search(r'[-+]', 'a+b') # 连字符放首位表示它本身
re.search(r'[^]]+', 'abc]') # 取反加右中括号:直到中括号为止
re.findall(r'[\d]', 'a1b2') # 简写类在类内仍然生效类内符号行为
| 符号 | 类内含义 | 要匹配本身时 |
|---|---|---|
| 点号与量词符号 | 普通字符 | 直接写即可 |
| 圆括号与竖线 | 普通字符 | 直接写即可 |
| 脱字符 | 首位为取反,否则普通 | 放非首位或转义 |
| 连字符 | 两端或转义为普通,中间为区间 | 放首位或末位 |
| 右中括号 | 结束类 | 放首位或转义 |
| 反斜杠 | 仍为转义符 | 写两个反斜杠 |
类内不认量词,写成星号或加号只是把这几个符号本身加入集合。想表示「某个字符重复若干次」,量词必须写在方括号之外。