12

我试图找到与原始模式字符串“远离”最多两个错误的字符串(即它们最多相差两个字母)。

但是,以下代码没有按我的预期工作,至少从我对模糊正则表达式的理解来看:

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 中,所以不可能是这样)。

我在这里想念什么?有没有办法让它在给定模式的 Hamming 2-ball 中只找到字符串?

字母交换是否有可能被认为只是一种变化?如果是这样 - 我该如何避免这种情况?

4

2 回答 2

16

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

>>> 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<=3} 最多允许 3 个错误
  • {1<=e<=3} 允许至少 1 个和最多 3 个错误

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

于 2017-10-03T08:50:16.890 回答
4

你的错误是假设“错误”与“替换”是一回事,但事实并非如此。

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

ATAGGAG-AAGATGATGTATA
ATAG-AGCAAGATGATGTATA

有没有办法让这个只找到给定模式的汉明 2 球内的字符串?

是的。请注意,汉明距离是一种编辑距离,它测量将一个字符串编辑为另一个等长字符串所需的最小替换次数。因此,要仅匹配 Hamming 2-ball 模式中的字符串,我们需要告诉regex匹配 2 个替换中的任何内容,我们可以通过使用s错误类型而不是e

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

字母交换是否有可能被认为只是一种变化?

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

于 2019-07-07T12:35:39.297 回答