如何找到不完美的子串?

时间:2013-03-20 13:23:26

标签: python regex python-2.7

我有一个相等长度的子串列表,所有这些我想在一个大字符串中找到一个位置。然而,棘手的部分是我应该找到具有有限数量的不匹配的子串(也给出了不匹配的数量)。我以为我可以用正则表达式做到这一点,但我无法找到。 UPD:我使用的是Python 2.7。

实施例: 输入字符串:s = 'ATGTCGATCGATGCTAGCTATAGATAAAA',输入子字符串是s0 = 'ATG',允许的不匹配数是n = 1.我想要的是返回一个可迭代的,让我们说一个位置列表:{{1 },对应于' ATG'的位置。 (两次),' ATA' (两次),' ATC'相应地,因为没有其他3-mers的错配不会出现在弦乐中。

3 个答案:

答案 0 :(得分:4)

新的regex模块支持模糊匹配。例如

(?:foo){s<=2} 

匹配“foo”,允许2次替换。

还要记录文档中的这句话:

  

默认情况下,模糊匹配搜索符合的第一个匹配项   给定约束。 ENHANCEMATCH标志将导致它尝试   改善匹配的拟合(即减少错误的数量)   它找到了。

     

BESTMATCH标志将使其搜索最佳匹配。

示例:

>>> regex.findall(r'(?:foo){s<=2}', 'xxfoo')
['xfo']
>>> regex.findall(r'(?:foo){s<=2}', 'xxfoo', regex.BESTMATCH)
['foo']

答案 1 :(得分:0)

您是否考虑过使用Levenshtein距离算法寻求帮助?它用于确定两个字符串彼此之间的相似程度。

这是一个天真的实现:

  1. 对于i = 0到len(haystack_str) - len(needle_str)
  2. 让potential_match = haystack_str [i,i + len]
  3. 看看在potential_match和needle_str之间的Levenshtein距离
  4. 如果距离为0,则表示您完美匹配
  5. 如果距离小于阈值,则表示您有一个不完美但足够接近的匹配
  6. 否则,继续下一个

答案 2 :(得分:0)

鉴于我对你的问题的理解:

输入1

def diff_count(s1, s2):
    count = 0
    for i in range(len(s1)):
        if s1[i] != s2[i]:
            count += 1
    return count

def diff_filter1(s1, s2, max_count):
    return diff_count(s1, s2) < max_count

类型2(效率更高)

def diff_filter2(s1, s2, max_count):
    count = 0
    i = 0
    while i < len(s1) and count < max_count:
        if s1[i] != s2[i]:
            count += 1
        i += 1
    return count < max_count

Levenshtein distance

的Python代码
def LevenshteinDistance(s, t):
    len_s = len(s)- 1
    len_t = len(t)- 1
    if(len_s == 0): return len_t
    if(len_t == 0): return len_s
    if(s[len_s-1] == t[len_t-1]): cost = 0
    else:                         cost = 1
    return min(LevenshteinDistance(s[0:len_s-1], t) + 1,
               LevenshteinDistance(s, t[0:len_t-1]) + 1,
               LevenshteinDistance(s[0:len_s-1], t[0:len_t-1]) + cost)