如何使用Python REGEX重新驱动模式中的特定术语



我的模式是

Forward primer
CGAAGCCTGGGGTGCCCGCGATTT Plus 24 1 24 71.81 66.67 4.00 2.00 
Reverse primer
AAATCGGTCCCATCACCTTCTTAT Minus 24 420 397 59.83 41.67 5.00 2.00 
Product length
420 

Products on potentially unintended templates

>CP049108.1 Mycobacterium tuberculosis strain 5005 chromosome, complete genome product length = 495
Forward primer  1        CGAAGCCTGGGGTGCCCGCGATTT  24
Template        1930054  ........................  1930077
Reverse primer  1        AAATCGGTCCCATCACCTTCTTAT  24
Template        1930548  ........................  1930525

product length = 2946
Forward primer  1        CGAAGCCTGGGGTGCCCGCGATTT  24
Template        1927603  .......C....C..T..T...G.  1927626
Reverse primer  1        AAATCGGTCCCATCACCTTCTTAT  24
Template        1930548  ........................  1930525

>CP046728.2 Mycobacterium tuberculosis strain TCDC11 chromosome, complete genome product length = 420
Forward primer  1        CGAAGCCTGGGGTGCCCGCGATTT  24
Template        2150761  ........................  2150784
Reverse primer  1        AAATCGGTCCCATCACCTTCTTAT  24
Template        2151180  ........................  2151157

product length = 2595
Forward primer  1        CGAAGCCTGGGGTGCCCGCGATTT  24
Template        2148586  .......C....C..T..T...G.  2148609
Reverse primer  1        AAATCGGTCCCATCACCTTCTTAT  24
Template        2151180  ........................  2151157

>CP047258.1 Mycobacterium tuberculosis strain TCDC3 chromosome product length = 345
Forward primer  1        CGAAGCCTGGGGTGCCCGCGATTT  24
Template        2166300  ........................  2166323
Reverse primer  1        AAATCGGTCCCATCACCTTCTTAT  24
Template        2166644  ........................  2166621

我需要的是

>CP049108.1 = 495   1930054 1930548 
>CP046728.2 = 420   2150761 2151180
>CP047258.1 = 345   2166300 2166644

我是微生物学家和Python初学者。我试过

import re
file = open(r"C:\Users\Lab\Desktop\amplicons\ETRA", "r")
handle = file.read()
file.close()
pattern1 = re.compile(r'>.{5,10}.d')
matches1 = pattern1.finditer(handle)
for match1 in matches1:
print(match1.group(0))

但我也需要在我的登录号之后出现特定条款(例如,登录号>CP049108.1(。我也会根据我的其他工作调整你的知识。

感谢您的帮助提前感谢

以下是我的想法->([wd]*?.d*?) .+= (d+)n.+n.*?(d+).+n{2}.+n.*?(d+)

让我们看一个只有一组数据的例子,只要global标志设置为True(在python中默认设置为True(,就可以输入粘贴的整个数据,并且仍然可以得到结果

>CP049108.1结核分枝杆菌菌株5005染色体,全基因组产物长度=495正向引物1
CGAAGCCTGGTGCCCGCGATTT 24模板1930054…………1930077

反向引物1 AAATCGGTCCCATCACCTTCAT24模板
1930548。。。。。。。。。。。。。。。。。。。。。。。。1930525

第一组将是-CP049108.1

第二组为495

第三组为1930054

第四组(也是最后一组(将是1930548

当然,现在你可以将整个数据重组为你想要的样子,如果你从文本文件中读取数据,你可以使用这个代码片段-

import re
with open('test.txt', 'r') as file:
content = file.read()
pattern = re.compile(r'>([wd]*?.d*?) .+= (d+)n.+n.*?(d+).+n{2}.+n.*?(d+)')
for match in pattern.finditer(content):
output = '>{} = {} {} {}'.format(match.group(1), match.group(2), match.group(3), match.group(4))
print(output)

如果我输入的正是你提供给test.txt的数据集,我会得到这个输出-

>CP049108.1 = 495   1930054 1930548
>CP046728.2 = 420   2150761 2151180
>CP047258.1 = 345   2166300 2166644

Regex解释

>(w+.d+) .+= (d+)n.+n.*?(d+).+n{2}.+n.*?(d+)

  • 让我们先分析第一行->(w+.d+) .+= (d+)n

    首先匹配CP049108,停止直到找到.(点(,然后匹配下一个数字,在本例中为1,停止直到达到=。然后,它将这些组合在一个捕获组中获得CP049108.1

    稍后,它将在=之后获取数字,并转到下一行,在这种情况下,它是495

  • 第二行时间-.+n

    是的,第二行被忽略了

  • 现在,第三条线路-.*?(d+).+n{2}

    它忽略所有内容,直到到达第一组数字,抓住这些数字并跳到下一行(2行新行(。在这种情况下,结果是1930054

  • 现在,第四行-.+n

    这也被忽略

  • 最后,最后一行-.*?(d+)

    这与第三行的工作原理完全相同,结果是1930548

查看演示!

您可以匹配以下正则表达式,然后提取三个捕获组的内容:

r'^(>CPd{6}.d).+?bproduct +length += +(d+).*?^Template +(d+).*?^Template +(d+)'gms

演示

这可以通过使用Python的VERBOSE(也称为X(标志进行自我文档化。

这源于Perl的自由间距模式,因为我不熟悉Python,所以我将使用它。不懂Perl的读者可以很好地理解这一点。

/
^                        # match beginning of line        
(>CPd{6}.d)           # match '>CP', 6 digits, '.', 1 digit in cap group 1  
.+?                      # match 0+ characters, lazily (`?`)
b                       # match a word break               
product +length += +  # match 'product', 1+ spaces, 'length', 1+ spaces,
#   '=', 1+ spaces 
(d+)                    # match 1+ digits in cap group 2
.*?                      # match 0+ characters, lazily (`?`)
^Template +             # match beginning of line, 'Template', 1+ spaces 
(d+)                    # match 1+ digits in cap group 3
.*?                      # match 0+ characters, lazily (`?`)
^Template +             # match beginning of line, 'Template', 1+ spaces 
(d+)                    # match 1+ digits in cap group 4                
/xgms                    # free-spacing, global, multiline, single-line modes

不同模式的含义在链接中给出。在自由间距模式下,在解析正则表达式之前,将删除字符类之外的非转义空格。因此,作为表达式一部分的空格,例如"乘积"one_answers"长度"之间的空格,必须受到保护。我已经选择在这里转义它们,但其他选项是将每个空格放在字符类([ ](中,使用Unicode表达式p{Space}[[:space:\,或者,如果合适的话,使用s(空白字符(。

这里有一种方法。regex搜索相当依赖于文本是否与您提供的文件一致。

rows = re.findall('(>.{5,10}).*length( = d*).*s*.*s*Templates*(   d*).*s*.*s*Templates*( d*)', handle)
print('n'.join(''.join(x) for x in rows))

这就是您所需要的:

matches=re.findall(r'(>.{5,10}.d).*?( = d+).*?Template.*?( d+).+?( d+)', handle, re.DOTALL)
["".join(x) for x in matches]

正如您所看到的,在regex中使用圆括号声明了四个组。每组将获取由空格分隔的输出的四个部分。您将加入这个结果以获得您想要的输出。

我建议您考虑一下需要的逻辑,然后编写规则来提供帮助。

这是一本我用来学习Regex的有用的书。它涵盖了您可以用来获得所需结果的基本规则:http://diveinto.org/python3/regular-expressions.html

最新更新