使用带有 re 的列表(或者如何删除可能的密码子列表之间的子字符串)

Using lists with re (Or how to delete a substring between a list of possible codons)

我正在编写一个脚本来从一系列基因中删除开放阅读框。我知道 re 模块,但我不太了解它在涉及列表时的正确用法 - 这是我的任务:

  1. 我需要找到基因中的起始密码子'AUG'

  2. 然后我需要找到存储在列表中的 3 个可能终止密码子之一的出现

    stop_codons = ['TAG', 'TAA', 'TGA']

  3. 然后我需要删除开始和之间的所有其他字符 终止密码子。

我取得了接近的成绩:

gene = 'AUGGTAAATTGAUUGUTAUTAUTGTAGTGATGU'
re.sub('AUG.+TAG', '', gene)

但是我觉得肯定有比为每个终止密码子写一行并循环遍历预定义列表更好的方法(一些线粒体基因组和细菌基因组有替代 start/stop 密码子和我希望可以轻松修改代码以在适当的时候包含这些密码子)。

如何使用 re 实现此目的?

下面的代码应该符合您的意思。它查找出现,然后打印 stop_codons 列表中每个项目的起始和终止密码子之间没有字符的切割基因。

import re

gene = 'AUGGTAAATTGAUUGUTAUTAUTGTAGTGATGU'
start_codon = 'AUG'
stop_codons = ['TAG', 'TAA', 'TGA']

for stop_codons_item in stop_codons:
  cut_gene = re.sub('(?<=%s).*?(?=%s)' % (start_codon,stop_codons_item), '', gene)
  print(cut_gene)

您的代码还在输出中削减 start_codonstop_codon。我不知道这是否是你想要达到的目标。如果是这样,只需将 cut_gene 变量替换为 for 循环中的 re.sub 示例行,如下所示:

re.sub(f'{start_codon}.+{stop_codons_item}', '', gene)

首先,请注意 re 尝试匹配最大可能的子字符串。这意味着天真的方法不会在第一个“结束”密码子处停止,而是在最后一个密码子处停止:

            start                   end1     end2
            vvv                     vvv      vvv
>>> gene = 'AUGGTAAATTGAUUGUTAUTAUTGTAGTGATGUTAGG'
>>> re.sub('AUG.+TAG', '', gene)
'G'

更好:

>>> re.sub('AUG.+?TAG', '', gene)
'TGATGUTAGG'

您可以通过在正则表达式中使用“A 或 B”类型的表达式来避免多次迭代字符串,这看起来像 (A|B)。在你的例子中:

          start end
            vvv vvv
>>> gene = 'AUGGTAAATTGAUUGUTAUTAUTGTAGTGATGUTAGG'
>>> re.sub('AUG.+?(TAG|TAA|TGA)', '', gene)
'TGATGUTAGG'