使用python在字符串中查找具有一定长度的重复

时间:2015-02-26 19:47:08

标签: python regex loops mismatch

我正在尝试使用regex模块在​​给定字符串(30个字符)中查找非重叠重复(重复的子字符串),具有以下要求:

  1. 我只对6-15个字符长的非重叠重复感兴趣。
  2. 允许1次不匹配
  3. 返回每场比赛的位置
  4. 我想到的一种方法是,对于每个可能的重复长度,让python循环遍历30char字符串输入。例如,

    string = "ATAGATATATGGCCCGGCCCATAGATATAT" #input
    
    #for 6char repeats, first one in loop would be for the following event:
    
    text = "ATAGAT"
    text2 ="(" + text + ")"+ "{e<=1}" #this is to allow 1 mismatch later in regex
    
    string2="ATATGGCCCGGCCCATAGATATAT" #string after excluding text
    
    for x in regex.finditer(text2,string2,overlapped=True):
        print x.span()
    
    #then still for 6char repeats, I will move on to text = "TAGATA"...
    #after 6char, loop again for 7char...
    

    此特定字符串应该有两个输出=&#34; ATAGATATAT GGCCCGGCCC ATAGATATAT &#34;。 1.大胆的两个&#34; ATAGATATAT&#34; + 1不匹配:&#34; ATAGATATATG&#34; &安培;&#34; CATAGATATAT&#34;位置索引返回为(0,10)&amp;(19,29); 2.&#34; TGGCCC&#34; &安培; &#34; GGCCCA&#34; (需要添加一个不匹配至少6个字符),索引(9,14)&amp;(15,20)。数字可以在列表或表格中。

    对不起,我没有包含真正的循环,但我希望这个想法很明确......正如你所看到的,这是一种非常低效的方法,更不用说它会创造出来了冗余---例如10char重复将被计数不止一次,因为它适合9,8,7和6个char重复循环。此外,我有很多这样的30个字符串可以使用,所以我很感激你对一些更干净的方法的建议。

    非常感谢:)

1 个答案:

答案 0 :(得分:1)

我会尝试直接算法而不是正则表达式(在这种情况下这很混乱);

s = "ATAGATATATGGCCCGGCCCATAGATATAT"

def fuzzy_compare(s1, s2):
    # sanity check
    if len(s1) != len(s2):
        return False

    diffs = 0
    for a, b in zip(s1, s2):
        if a != b:
            diffs += 1

        if diffs > 1:
            return False        

    return True

slen = len(s) # 30
for l in range(6, 16):
  i = 0
  while (i + l * 2) <= slen:
    sub1 = s[i:i+l]
    for j in range(i+l, slen - l):
        sub2 = s[j:j+l]
        if fuzzy_compare(sub1, sub2):
            # checking if this could be partial
            partial = False
            if i + l < j and j + l < slen:
                extsub1 = s[i:i+l+1]
                extsub2 = s[j:j+l+1]
                # if it is partial, we'll get it later in the main loop
                if fuzzy_compare(extsub1, extsub2):
                   partial = True

            if not partial: 
                print (i, i+l), (j, j+l)

    i += 1

这是初稿,所以请随意尝试一下。它似乎也很笨重而且不是最优的,但首先尝试运行它 - 它可能足够了。