查找每个字母至少重复一次的正则表达式

Finding regular expression with at least one repetition of each letter

从任何 *.fasta DNA 序列(仅 'ACTG' 个字符)中,我必须找到每个字母至少包含一次重复的所有序列。

例如从序列 'AAGTCCTAG' 我应该能够找到:'AAGTC'、'AGTC'、'GTCCTA'、'TCCTAG'、'CCTAG'和 'CTAG'(每个字母的迭代)。

我不知道如何在 pyhton 2.7 中做到这一点。我正在尝试使用正则表达式,但它并没有搜索所有变体。

我怎样才能做到这一点?

如果您可以将序列分解成一个列表,例如5 个字母的序列,然后您可以使用此函数查找重复序列。

from itertools import groupby
import numpy as np

def find_repeats(input_list, n_repeats):
    flagged_items = []

    for item in input_list:
        # Create itertools.groupby object
        groups = groupby(str(item))

        # Create list of tuples: (digit, number of repeats)
        result = [(label, sum(1 for _ in group)) for label, group in groups]

        # Extract just number of repeats
        char_lens = np.array([x[1] for x in result])   

        # Append to flagged items
        if any(char_lens >= n_repeats):
            flagged_items.append(item)

    # Return flagged items
    return flagged_items

#--------------------------------------
test_list = ['aatcg', 'ctagg', 'catcg']

find_repeats(test_list, n_repeats=2)  # Returns ['aatcg', 'ctagg']

您可以找到所有长度为 4+ 的子字符串,然后从中向下 select 以仅找到包含每个字母之一的最短可能组合:

s = 'AAGTCCTAG'

def get_shortest(s):
  l, b = len(s), set('ATCG')
  options = [s[i:j+1] for i in range(l) for j in range(i,l) if (j+1)-i > 3]
  return [i for i in options if len(set(i) & b) == 4 and (set(i) != set(i[:-1]))]

print(get_shortest(s))

输出:

['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']

这是您可以使用的另一种方法。也许不像 chrisz answere 那样快速和漂亮。但对于初学者来说可能更容易阅读和理解。

DNA='AAGTCCTAG'
toSave=[]
for i in range(len(DNA)):
    letters=['A','G','T','C']
    j=i
    seq=[]
    while len(letters)>0 and j<(len(DNA)):
        seq.append(DNA[j])
        try:
            letters.remove(DNA[j])
        except:
            pass
        j+=1
    if len(letters)==0:
        toSave.append(seq)

print(toSave)

由于您要查找的子字符串可能具有任意长度,因此后进先出队列似乎可行。一次附加每个字母,检查每个字母是否至少有一个。如果找到return它。然后去掉前面的字母,继续检查,直到不再有效。

def find_agtc_seq(seq_in):
    chars = 'AGTC'
    cur_str = []
    for ch in seq_in:
        cur_str.append(ch)
        while all(map(cur_str.count,chars)):
            yield("".join(cur_str))
            cur_str.pop(0)

seq = 'AAGTCCTAG'
for substr in find_agtc_seq(seq):
    print(substr)

这似乎会导致您要查找的子字符串:

AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG

我真的很想为此创建一个简短的答案,所以这就是我想出的!

See code in use here

s = 'AAGTCCTAG'
d = 'ACGT'
c = len(d)

while c <= len(s):
    x,c = s[:c],c+1
    if all(l in x for l in d):
        print(x)
        s,c = s[1:],len(d)

它的工作原理如下:

  • c设置为我们确保字符串中存在的字符串的长度(d = ACGT)
  • while 循环遍历 s 的每个可能的子字符串,使得 c 小于 s 的长度。
    • 这通过在 while 循环的每次迭代中将 c 增加 1 来实现。
    • 如果我们的字符串 d (ACGT) 中的每个字符都存在于子字符串中,我们打印结果,将 c 重置为其默认值并将字符串切片 1 个字符从头开始。
    • 循环继续,直到字符串 sd

结果:

AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG

改为在列表中获取输出 (see code in use here):

s = 'AAGTCCTAG'
d = 'ACGT'
c,r = len(d),[]

while c <= len(s):
    x,c = s[:c],c+1
    if all(l in x for l in d):
        r.append(x)
        s,c = s[1:],len(d)

print(r)

结果:

['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']