Python regex为何优先匹配长模糊匹配而非短精确匹配?
问题:Python regex模糊匹配返回带错配结果而非精确匹配?
代码示例与实际结果
import regex s = "vrhvydhvkzejjvksdlstringvhehvehvurejlcslvdk" #待搜索字符串 p = ['(?P<string>string)', '(?P<longtext>longtext)'] #待匹配模式 r = regex.compile('(?b)(' + " | ".join(p) + '){s<=3}') #允许最多3个错配的正则,返回最佳匹配 result = r.search(s) print(result) # 实际输出:<regex.Match object; span=(18, 25), match='stringv', fuzzy_counts=(1, 0, 0)>
预期结果
<regex.Match object; span=(18, 24), match='string', fuzzy_counts=(0, 0, 0)>
原因分析
- 模糊匹配约束作用范围错误:你将
{s<=3}应用在整个(string|longtext)分组上,而非每个单独的模式。这会让regex将整个分组作为模糊匹配单元,尝试匹配尽可能长的子串,哪怕需要引入错配。 - 旧版regex库的匹配逻辑:在你使用的regex 2.5.115版本中,启用
(?b)最佳匹配模式时,若存在多个候选匹配,会优先选择更长的匹配,而非错配数最少的精确匹配——哪怕精确匹配的错配数为0,只要更长的匹配错配数在允许范围内,就会被优先返回。
解决方案
方法1:将模糊匹配约束应用到每个独立模式
修改正则编译逻辑,把{s<=3}分别添加到每个模式后,确保每个模式单独执行模糊匹配,此时regex会优先选择错配数最少的精确匹配:
import regex s = "vrhvydhvkzejjvksdlstringvhehvehvurejlcslvdk" p = ['(?P<string>string){s<=3}', '(?P<longtext>longtext){s<=3}'] r = regex.compile('(?b)' + " | ".join(p)) result = r.search(s) print(result) # 输出:<regex.Match object; span=(18, 24), match='string', fuzzy_counts=(0, 0, 0)>
方法2:添加边界限制(可选)
如果目标模式是独立子串(不会出现在其他长串内部),可以给每个模式添加单词边界\b,避免匹配包含目标模式的更长子串:
import regex s = "vrhvydhvkzejjvksdlstringvhehvehvurejlcslvdk" p = ['(?P<string>\bstring\b){s<=3}', '(?P<longtext>\blongtext\b){s<=3}'] r = regex.compile('(?b)' + " | ".join(p)) result = r.search(s) print(result)
注意:若目标模式本身可能出现在单词中间,此方法不适用。
内容的提问来源于stack exchange,提问作者Agathe
相关产品推荐
相关产品推荐

