当模式以一个有范围的 (?a:...) 或 (?u:...) 组开头时,re.search() 会丢失匹配
作者: BwL1289创建于 2026年9月29日更新于 2026年9月29日
标签type-bugtopic-regex
原因。 _compile_info() 构建了 SRE(search) 使用来跳过开始位置的"字符集"预过滤器。_get_charset_prefix() 会查看前缀组并合并它们的标记(Lib/re/_optimizer.py:331,主分支为 a57d16507cccb69d3d76ae05b52f01627d0bc479)。它只返回字符集,而 _compile_info() 会将该字符集与模式的标记进行编译(:428)。因此,组中的类别转义(\w、\W、\d、\D、\s、\S)在预过滤器中获得模式的字符类型,而在模式体中获得组的类型。re.DEBUG 显示了不匹配(3.14.5):
>>> re.compile(r'(?u:\w)', re.ASCII | re.DEBUG)
SUBPATTERN None 32 0
IN
CATEGORY CATEGORY_WORD
0. INFO 7 0b100 1 1 (to 8)
in
5. CATEGORY WORD <- the prefilter: ASCII \w
7. FAILURE
8: IN 4 (to 13)
10. CATEGORY UNI_WORD <- the pattern: Unicode \w
12. FAILURE
13: SUCCESS匹配在预过滤器的集合比模式体窄的地方丢失。这涵盖了在 ASCII 模式中的 (?u:...) 中的 Unicode 类,以及在默认 str 模式中的 (?a:...) 中的否定类(\W、\D、\S)。如果预过滤器更宽(str 模式中的 (?a:\w)),则只会影响速度。显式集合(如 [a-z])不依赖类型标记,因此不会受影响。对于字节模式,(?L:...) 会经过相同的代码,但我无法测试它:没有可用的单字节本地化。
内容来源: python/cpython