9

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

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

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

       Length = 2575

(一些文字)

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

       Length = 2575

(一些文字)

(ETC...)

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

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

print match[0]

当 Length 行是 > 行的下一行时,它可以很好地提取记录。

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

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

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

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

4

2 回答 2

4

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

>>> x = """
... >U51677 人类非组蛋白染色质蛋白 HMG1 (HMG1) 基因,完整
...
...光盘。#一些记录没有这一行(见下文)
...
... 长度 = 2575
...(一些文字)
...
... >U51677 人类非组蛋白染色质蛋白 HMG1 (HMG1) 基因,完整
...
... 长度 = 2575
...(一些文字)
...
... (ETC...)
……“”“
>>> re.search("^(>.*)\n.*(?:\n*.?)Length\s=\s(\d+)", x, re.MULTILINE|re.DOTALL)
<_sre.SRE_Match 对象位于 0x10c937e00>
>>> _.group(2)
'2575'

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

>>> re.findall("^(>.*?)$.*?Length\s=\s(\d+)", x, re.MULTILINE|re.DOTALL)
[('>U51677人非组蛋白染色质蛋白HMG1(HMG1)基因,完整','2575'),('>U51677人非组蛋白染色质蛋白HMG1(HMG1)基因,完整','2575')]
于 2012-10-28T16:59:31.690 回答
0

试试这个正则表达式:

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

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

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

您之前尝试的问题似乎是,您使用.*的可以匹配任何东西并且同时是贪婪的(因此它会尽可能多地消耗,包括以下Length = 2575.

于 2012-10-28T17:01:53.503 回答