编辑行并从fi中删除行

2024-04-25 10:07:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个登记号和16srrna序列的文件,我要做的是删除所有的RNA序列,只保留登记号和物种名称的序列(并删除中间的所有垃圾)。因此,我的输入文件如下所示(登记号前面有>;):

> D50541 1 1409 1409bp rna Abiotrophia defectiva Aerococcaceae
CUGGCGGCGU GCCUAAUACA UGCAAGUCGA ACCGAAGCAU CUUCGGAUGC UUAGUGGCGA ACGGGUGAGU AACACGUAGA UAACCUACCC UAGACUCGAG GAUAACUCCG GGAAACUGGA GCUAAUACUG GAUAGGAUAU AGAGAUAAUU UCUUUAUAUU (... and many more lines)

> AY538167 1 1411 1411bp rna Acholeplasma hippikon Acholeplasmataceae
CUGGCGGCGU GCCUAAUACA UGCAAGUCGA ACGCUCUAUA GCAAUAUAGG GAGUGGCGAA CGGGUGAGUA ACACGUAGAU AACCUACCCU UACUUCGAGG AUAACUUCGG GAAACUGGAG CUAAUACUGG AUAGGACAUA UUGAGGCAUC UUAAUAUGUU ...

我希望我的输出如下所示:

>D50541 Abiotrophia defectiva Aerococcaceae

>AY538167 Acholeplasma hippikon Acholeplasmataceae

我写的代码符合我的要求。。。对于大多数线路。看起来是这样的:

    #!/usr/bin/env python

    # take LTPs111.compressed fasta and reduce to accession numbers with names.
    import re
    infilename = 'LTPs111.compressed.fasta'
    outfilename = 'acs.fasta'

    regex = re.compile(r'(>)\s(\w+).+[rna]\s+([A-Z].+)')    

    #remove extra letters and spaces
    with open(infilename, 'r') as infile, open(outfilename, 'w') as outfile:
        for line in infile:
            x = regex.sub(r'\1\2 \3', line)
    #remove rna sequences
        for line in x:
            if '>' in line:
                outfile.write(x)

有时,代码似乎跳过了一些名称。例如,对于上面的第一个登录号,我只得到了:

>D50541 Aerococcaceae

为什么我的代码会这样做?每个登录号的输入看起来是相同的,并且每行的“rna”和名字之间的间隔是相同的(5个空格)。你知道吗

感谢任何有想法的人!你知道吗


Tags: and文件代码in名称line序列fasta
2条回答

我仍然无法运行您的代码以获得声明的结果,但我想我知道问题是什么:

>>> line = '> AY538167 1 1411 1411bp rna Acholeplasma hippikon Acholeplasmataceae'
>>> regex = re.compile(r'(>)\s(\w+).+[rna]\s+([A-Z].+)')
>>> regex.findall(line)
[('>', 'AY538167', 'Acholeplasmataceae')]

问题是[rna]\s+匹配单词末尾的任何字符rna。而且,因为所有的匹配都是贪婪的,没有向前看或其他任何东西来阻止它,这意味着它匹配n末尾的hippikon。你知道吗

简单的解决方案是去掉括号,这样它就匹配了字符串rna

>>> regex = re.compile(r'(>)\s(\w+).+rna\s+([A-Z].+)')

如果你的任何一个物种或属都能以这个字符串结尾,那就行不通了。有这样的名字吗?如果是这样,您需要想出更好的方法来描述1409bp部分和rna部分之间的截止点。最简单的方法可能是寻找被空格包围的rna

>>> regex = re.compile(r'(>)\s(\w+).+\s+rna\s+([A-Z].+)')

不管这是不是真的正确,我不能说不知道更多的格式,但希望你了解我做得足够好,以验证它的正确性(或至少提出比我能问的更聪明的问题)。你知道吗


添加捕获组可能有助于调试。例如,与此相反:

(>)\s(\w+).+[rna]\s+([A-Z].+)

…搜索:

(>)(\s)(\w+)(.+[rna]\s+)([A-Z].+)

很明显,您想要的捕获组现在是\1\3 \5,而不是\1\2 \3……但重要的是,您可以看到在\4中匹配的内容:

[('>', ' ', 'AY538167', ' 1 1411 1411bp Acholeplasma hippikon ', 'Acholeplasmataceae')]

所以,现在的问题是“为什么.+[rna]\s+匹配'1 1411 1411bp Acholeplasma hippikon '?”?有时上下文很重要,但在本例中,它并不重要。您不希望该组与任何上下文中的字符串匹配,但它将始终与之匹配,因此这是您必须调试的部分。你知道吗


另外,一个可视化的regexp资源管理器通常有很大的帮助。最好的可以给表达式和匹配的文本等部分上色,向您展示regexp是如何以及为什么这样做的。你知道吗

当然,您受到在您的平台上或在线上运行的、使用Python语法的限制。如果您很小心并且/或者只使用简单的特性(在您的示例中),perl/PCRE语法与Python非常接近,JavaScript/ActionScript也非常接近(需要记住的一个大区别是replace/sub使用$而不是\1)。你知道吗

我没有一个好的在线推荐,但从快速浏览Debuggex看起来很酷。你知道吗

方括号之间的项是字符类,因此通过将regex设置为查找“[rna]”,您请求的行是r、n或a,而不是全部3行。你知道吗

此外,如果你想要的线都有“bp-rna”的模式,我会用它来拉这些线。通过逐行读取文件,以下内容对我来说非常有用,例如:

regex = re.compile(r'^[\w\s]+bp rna .*$')

但是,同样,如果只需查找其中包含“bp-rna”的行,就可以逐行读取文件并完全放弃regex:

for line in file:
   if "bp rna" in line:
     print(line) 

编辑:由于没有仔细阅读请求,我搞砸了。也许捕获并替换正则表达式会有所帮助?你知道吗

for line in file:
  if "bp rna" in line:
    subreg = re.sub(r'^(>[\w]+)\s[\d\s]+bp\srna\s([\w\s]+$)', r"\1 \2", line)
    print(subreg)

输出:

>AY538166 Acholeplasma granularum Acholeplasmataceae

>AY538167 Acholeplasma hippikon Acholeplasmataceae

这应该匹配您想要的东西之间的任何空白(制表符或空格)。你知道吗

相关问题 更多 >