模糊正则表达式(例如{e <= 2})在Python中正确使用

时间:2017-10-03 08:15:56

标签: python regex fuzzy-search

我试图找到最多两个错误的字符串&#39;远离&#39;来自原始模式字符串(即它们最多相差两个字母)。

但是,下面的代码并没有像我期望的那样工作,至少不是我对模糊正则表达式的理解:

import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){e<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
>> ['ATAGAGCAAGATGATGTATA']  # the second string

如您所见,两个字符串在三个字母上有所不同,而不是最多两个:

第一个:ATAG GAG AAGATGATGTATA

第二个:ATAG AGC AAGATGATGTATA

然后结果显示第二个字符串,好像它在e <= 2之内(这也发生在重叠= False,因此不能这样)。

我在这里缺少什么?有没有办法让这个只能在给定模式的汉明2球中找到弦?

字母交换是否可能只被视为一次更改?如果是这样 - 我怎么能避免这种情况?

谢谢!

2 个答案:

答案 0 :(得分:2)

让我们检查这个片段的模糊计数:

>>> pattern_string = 'ATAGGAGAAGATGATGTATA'
>>> query_string = 'ATAGAGCAAGATGATGTATA'
>>> r = regex.compile('(%s){e<=2}' % pattern_string)
>>> r.match(query_string)
<regex.Match object; span=(0, 20), match='ATAGAGCAAGATGATGTATA', fuzzy_counts=(0, 1, 1)>

fuzzy_counts=(0, 1, 1)表示在这种情况下,我们没有替换,1次插入和1次删除。因此,您的过滤器有效,因为错误总数为2。

但似乎你只需要通过替换计数来过滤,所以你可以修改正则表达式:

import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res

docs

中查看这个很棒的例子
  • {i <= 3}允许最多3次插入,但没有其他类型
  • {d <= 3}许可 最多3次删除,但没有其他类型
  • {s <= 3}允许最多3个 替换,但没有其他类型
  • {i <= 1,s <= 2}允许最多1 插入和最多2次替换,但没有删除
  • {e&lt; = 3}许可 最多3个错误
  • {1&lt; = e&lt; = 3}允许至少1次,最多3次错误

  • {i <= 2,d <= 2,e <= 3}允许最多2次插入,最多2次删除, 最多3个错误,但没有替换

答案 1 :(得分:0)

您的错误是假设“错误”与“替代”是同一回事。

regex包的模糊匹配可以理解三种错误-插入,删除和替换。如您所用,用e指定的错误距离可以由这些错误的任意组合组成。 ATAGGAGAAGATGATGTATA只需两个操作(1个删除和1个插入)就可以编辑为ATAGAGCAAGATGATGTATA,如下面的序列比对所示:

ATAGGAG-AAGATGATGTATA
ATAG-AGCAAGATGATGTATA
  

有什么办法让它仅在给定模式的汉明2球内找到弦?

是的。请注意,Hamming distance是一种编辑距离,它测量将一个字符串编辑为相等长度的另一个字符串所需的最小替代数量。因此,仅在模式的Hamming 2球内匹配字符串,我们需要告诉regex匹配2个替代中的任何字符,我们可以使用s错误来进行匹配类型而不是e

import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
  

交换字母是否有可能只是一次更改?

目前不在regex软件包中。两个字符“交换”的标准术语是“换位”。确实存在包括转置作为可能的编辑的编辑距离(例如Dameau-Levenshtein distance,其中编辑可以是相邻字符的插入,替换,删除或转置),并且对于某些应用程序(例如拼写错误)有用。但是,在撰写本文时,regex软件包中的模糊匹配根本不支持它们。