取反类的语义
在类的首位写脱字符,表示「不属于这组字符的任意一个字符」。它依然只消耗一个字符,也依然要求这个字符存在:取反类不会凭空匹配空字符串,只是把候选集合换成了补集。
和点号的关键差别
点号默认不匹配换行,取反类在多数引擎里默认包含换行,这个不对称是很多「结果多出一行」问题的根源。想让它也不吃换行,必须在类里显式排除换行符。
基本信息
| 写法 | 左中括号后紧跟脱字符,例如 脱字符加 0 到 9 |
|---|---|
| 消耗字符数 | 恒为 1,不会因为候选集合变大而多消耗 |
| 是否含换行 | PCRE、Python、Java、JS 等默认包含换行,与点号相反 |
| 与否定简写关系 | 取反数字类等价于大写的反斜杠 D,取反空白类等价于大写的反斜杠 S |
| 脱字符位置 | 只有写在首位才是取反,写在其他位置就是普通字符 |
典型使用场景
- 按分隔符切分字符串:取反分隔符类加号,一次切出一整段
- 校验字段里没有出现禁用字符,例如不允许出现空格与引号
- 提取引号之间的内容,前提是约定内容里不出现引号
- 去掉不可见字符之外的所有内容时,用取反不可见字符类反向筛选
- 在日志里跳过固定前缀,快速定位到第一个非空白非分隔符的字符
取反类的常见写法
取反类的常见写法
import re
re.findall(r'[^,]+', 'a,b,cc') # 按逗号切出三段内容
re.findall(r'[^,]+', 'a,\n,b') # 注意:换行也会被吞进片段里
re.findall(r'[^,\n]+', 'a,\n,b') # 显式排除换行才符合多数预期
re.search(r'^[^,]+$', 'abc') # 整行不含逗号,可作校验
re.findall(r'[^\d]+', 'a1b2') # 非数字片段
re.findall(r'[^\s]+', ' a b ') # 等价于按空白切词取反写法与否定简写
| 写法 | 含义 | 注意点 |
|---|---|---|
| 取反数字类 | 不是数字的任意字符 | 与反斜杠 D 等价 |
| 取反单词类 | 不是字母数字下划线的任意字符 | 与反斜杠 W 等价 |
| 取反空白类 | 不是空白的任意字符 | 与反斜杠 S 等价 |
| 取反自定义集合 | 补集只能手写 | 没有对应的简写形式 |
| 双重取反 | 类内先取反再排除 | 写法冗长,容易看错,建议拆成两步 |
取反类默认包含换行,跨行文本里用它做分割会把多行粘成一段。除非确实想跨行,否则一律在类里补上换行符,或改用不包含换行的显式集合。
取反类判断的是「单字符是否属于补集」,不关心上下文。想表达「这一行不含某串」,必须配合行锚点写成整行约束,否则只要行里有一个非禁用字符就会命中。