模糊正则表达式(例如 {e<=2})在 Python 中的正确用法
Fuzzy regex (e.g. {e<=2}) correct usage in Python
我试图找到与原始模式字符串最多有两个错误 'away' 的字符串(即它们最多相差两个字母)。
但是,下面的代码并没有像我预期的那样工作,至少从我对模糊正则表达式的理解来看是这样的:
import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){e<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
>> ['ATAGAGCAAGATGATGTATA'] # the second string
如您所见,两个字符串在三个字母上不同,而不是最多两个:
第一个有:ATAGGAGAAGATGATGTATA
第二个有:ATAGAGCAAGATGATGTATA
但结果显示第二个字符串,就好像它在 e<=2 内一样(这也发生在 overlapped=False 的情况下,所以不可能是这样)。
我在这里错过了什么?有没有办法让它只找到给定模式的汉明 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<=3} 允许
最多 3 个错误
{1<=e<=3} 允许至少 1 个和最多 3 个错误
{i<=2,d<=2,e<=3} 允许最多 2 次插入,最多 2 次删除,在
最多 3 个错误,但没有替换
您的错误是认为 "errors" 与 "substitutions" 是同一回事,但事实并非如此。
regex
包的模糊匹配理解三种错误——插入、删除和替换。如您所用,用 e
指定的误差距离可以由这些误差的任意组合组成。而ATAGGAGAAGATGATGTATA
只需要两次这样的操作(1次删除和1次插入)就可以编辑成ATAGAGCAAGATGATGTATA
,如下图序列比对所示:
ATAGGAG-AAGATGATGTATA
ATAG-AGCAAGATGATGTATA
is there any way of getting this to find only strings within the Hamming 2-ball of the given pattern?
是的。请注意,Hamming distance 是一种编辑距离,用于衡量将一个字符串编辑为另一个等长字符串所需的 替换 的最小数量。因此,为了仅匹配汉明 2 球模式中的字符串,我们需要告诉 regex
匹配 2 substitutions 中的任何内容,我们可以使用 [=17] =] 错误类型而不是 e
:
import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
Is it possible that a swap of letters is considered to be only one change?
目前不在 regex
包中。两个字符的 "swap" 的标准术语是 "transposition"。包含换位作为可能编辑的编辑距离(例如 Dameau-Levenshtein distance,其中编辑可以是相邻字符的插入、替换、删除或换位)确实存在并且对某些应用程序很有用(例如拼写错误更正)。然而,在撰写本文时,regex
包中的模糊匹配根本不支持它们。
我试图找到与原始模式字符串最多有两个错误 'away' 的字符串(即它们最多相差两个字母)。
但是,下面的代码并没有像我预期的那样工作,至少从我对模糊正则表达式的理解来看是这样的:
import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){e<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
>> ['ATAGAGCAAGATGATGTATA'] # the second string
如您所见,两个字符串在三个字母上不同,而不是最多两个:
第一个有:ATAGGAGAAGATGATGTATA
第二个有:ATAGAGCAAGATGATGTATA
但结果显示第二个字符串,就好像它在 e<=2 内一样(这也发生在 overlapped=False 的情况下,所以不可能是这样)。
我在这里错过了什么?有没有办法让它只找到给定模式的汉明 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<=3} 允许 最多 3 个错误
{1<=e<=3} 允许至少 1 个和最多 3 个错误
{i<=2,d<=2,e<=3} 允许最多 2 次插入,最多 2 次删除,在 最多 3 个错误,但没有替换
您的错误是认为 "errors" 与 "substitutions" 是同一回事,但事实并非如此。
regex
包的模糊匹配理解三种错误——插入、删除和替换。如您所用,用 e
指定的误差距离可以由这些误差的任意组合组成。而ATAGGAGAAGATGATGTATA
只需要两次这样的操作(1次删除和1次插入)就可以编辑成ATAGAGCAAGATGATGTATA
,如下图序列比对所示:
ATAGGAG-AAGATGATGTATA
ATAG-AGCAAGATGATGTATA
is there any way of getting this to find only strings within the Hamming 2-ball of the given pattern?
是的。请注意,Hamming distance 是一种编辑距离,用于衡量将一个字符串编辑为另一个等长字符串所需的 替换 的最小数量。因此,为了仅匹配汉明 2 球模式中的字符串,我们需要告诉 regex
匹配 2 substitutions 中的任何内容,我们可以使用 [=17] =] 错误类型而不是 e
:
import regex
res = regex.findall("(ATAGGAGAAGATGATGTATA){s<=2}", "ATAGAGCAAGATGATGTATA", overlapped=True)
print res
Is it possible that a swap of letters is considered to be only one change?
目前不在 regex
包中。两个字符的 "swap" 的标准术语是 "transposition"。包含换位作为可能编辑的编辑距离(例如 Dameau-Levenshtein distance,其中编辑可以是相邻字符的插入、替换、删除或换位)确实存在并且对某些应用程序很有用(例如拼写错误更正)。然而,在撰写本文时,regex
包中的模糊匹配根本不支持它们。