使用re.MULTILINE和re.DOTALL一起使用python

时间:2012-10-28 16:52:57

标签: python regex

基本上输入文件是这样的:

  

> U51677人非组蛋白染色质蛋白HMG1(HMG1)基因,完整

       cds. #some records don't have this line (see below)

       Length = 2575
     

(某些文字)

     

> U51677人非组蛋白染色质蛋白HMG1(HMG1)基因,完整

       Length = 2575
     

(某些文字)

     

(等...)

现在我写这个来提取以>开头的行和长度的数量

import re
regex = re.compile("^(>.*)\r\n.*Length\s=\s(\d+)", re.MULTILINE)
match = regex.findall(sample_blast.read())

print match[0]
当长度线是>的下一行时,

适用于提取记录。线。

然后我尝试了re.DOTALL,它应该使任何记录匹配(。* Length),无论是否有额外的行。

regex = re.compile("^(>.*)\r\n.*(?:\r\n*.?)Length\s=\s(\d+)", re.MULTILINE|re.DOTALL)

但它不起作用。我尝试了re.MULTILINE和re.DOTALL而不是管道,但仍然无法正常工作。

所以问题是如何创建一个匹配记录的正则表达式并返回所需的组,而不管记录中是否有额外的行。如果有人能够在re.VERBOSE中展示这一点,那将会很好。对不起,很长的帖子,并提前感谢您的任何帮助。 :)

2 个答案:

答案 0 :(得分:4)

您的问题可能是您使用\r\n。相反,请尝试仅使用\n

>>> x = """
... >U51677 Human non-histone chromatin protein HMG1 (HMG1) gene, complete
... 
...        cds. #some records don't have this line (see below)
... 
...        Length = 2575
... (some text)
... 
... >U51677 Human non-histone chromatin protein HMG1 (HMG1) gene, complete
... 
...        Length = 2575
... (some text)
... 
... (etc...)
... """
>>> re.search("^(>.*)\n.*(?:\n*.?)Length\s=\s(\d+)", x, re.MULTILINE|re.DOTALL)
<_sre.SRE_Match object at 0x10c937e00>
>>> _.group(2)
'2575'

此外,您的第一个.*太贪心了。相反,请尝试使用:^(>.*?)$.*?Length\s=\s(\d+)

>>> re.findall("^(>.*?)$.*?Length\s=\s(\d+)", x, re.MULTILINE|re.DOTALL)
[('>U51677 Human non-histone chromatin protein HMG1 (HMG1) gene, complete', '2575'), ('>U51677 Human non-histone chromatin protein HMG1 (HMG1) gene, complete', '2575')]

答案 1 :(得分:0)

试试这个正则表达式:

"^(>[^\r\n]*).*?Length\s=\s(\d+)"

设置两个选项(使用管道符号)。

第一个捕获组将匹配>之后的第一个换行符(与操作系统无关)。然后,.*?将匹配任何字符,直到遇到第一个 Length为止。其余的与您的第一次尝试相同。

您之前尝试的问题似乎是,您使用.*可以匹配任何内容并且同时贪婪(因此会消耗尽可能多的内容,包括以下{{1} }。