正则表达式"{m, n}?$"意外匹配行为的原因咨询
正则表达式
a{1,4}?$匹配结果的解释 先看你给出的测试代码:
>>> import sys, re >>> sys.version '3.11.5 (main, Sep 11 2023, 13:23:44) [GCC 11.2.0]' >>> re.__version__ '2.2.1' >>> re.findall('a{1,4}', 'aaaaa') ['aaaa', 'a'] >>> re.findall('a{1,4}?', 'aaaaa') ['a', 'a', 'a', 'a', 'a'] >>> re.findall('a{1,4}?$', 'aaaaa') ['aaaa']
你预期最后一条返回单个'a',实际得到'aaaa',原因可以拆解为三点:
- 锚点
$的约束:$要求匹配的子串必须紧贴字符串末尾,也就是说,匹配的子串的结束位置必须是整个字符串的最后一个字符位置。 - 正则引擎的扫描逻辑:引擎从左到右扫描字符串,逐个位置尝试匹配整个模式。当它走到第2个
a的位置(索引1)时,尝试匹配4个a刚好覆盖到字符串末尾(索引5),完全满足a{1,4}?$的要求,这个匹配就被记录下来。 - 非贪婪量词的实际表现:
{1,4}?虽然是非贪婪(优先匹配最少字符),但它必须满足$的约束。在前面的位置(比如索引0)尝试匹配1个a时,后面还有4个a,不满足$;逐步增加匹配长度到4个a,后面还是有1个a,依然不满足。直到移动到索引1的位置,匹配4个a刚好到末尾,这个匹配才成立。而一旦这个匹配被记录,findall会跳过已匹配的区域(这里是索引1到5),剩下的位置没有字符可匹配,自然不会再找到末尾的单个a。
内容的提问来源于stack exchange,提问作者rasul
相关产品推荐
相关产品推荐

