Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 匹配多行文本块的正则表达式_Python_Regex_Multiline - Fatal编程技术网

Python 匹配多行文本块的正则表达式

Python 匹配多行文本块的正则表达式,python,regex,multiline,Python,Regex,Multiline,在匹配跨多行的文本时,让Python正则表达式工作起来有点困难。示例文本为(“\n”是换行符) 一些不同的文本\n \n DSJFKDAFKJKDAFJDSAKFJADSFLKDLAFKDSAF\n [以上更多内容,以换行符结尾]\n [是的,这里的行数可变]\n \n (将上述步骤重复几百次)。 我想捕获两件事:“some_variable_TEXT”部分,以及在一次捕获中位于它下面两行的所有大写文本行(稍后我可以去掉换行符)。 我尝试了几种方法: re.compile(r"^>(\w

在匹配跨多行的文本时,让Python正则表达式工作起来有点困难。示例文本为(“\n”是换行符)

一些不同的文本\n
\n
DSJFKDAFKJKDAFJDSAKFJADSFLKDLAFKDSAF\n
[以上更多内容,以换行符结尾]\n
[是的,这里的行数可变]\n
\n
(将上述步骤重复几百次)。
我想捕获两件事:“some_variable_TEXT”部分,以及在一次捕获中位于它下面两行的所有大写文本行(稍后我可以去掉换行符)。 我尝试了几种方法:

re.compile(r"^>(\w+)$$([.$]+)^$", re.MULTILINE) # try to capture both parts
re.compile(r"(^[^>][\w\s]+)$", re.MULTILINE|re.DOTALL) # just textlines
这里有很多变化,没有运气。最后一行似乎一行一行地匹配文本,这不是我真正想要的。我能听懂第一部分,没问题,但我似乎听不懂4-5行大写字母。 我希望match.group(1)是一些不同的文本,group(2)是line1+line2+line3+等等,直到遇到空行为止

如果有人好奇,它应该是组成蛋白质的氨基酸序列。

找到:

^>([^\n\r]+)[\n\r]([A-Z\n\r]+)
\1=一些不同的文本

\2=所有盖的线

编辑(证明其有效):

text = """> some_Varying_TEXT

DSJFKDAFJKDAFJDSAKFJADSFLKDLAFKDSAF
GATACAACATAGGATACA
GGGGGAAAAAAAATTTTTTTTT
CCCCAAAA

> some_Varying_TEXT2

DJASDFHKJFHKSDHF
HHASGDFTERYTERE
GAGAGAGAGAG
PPPPPAAAAAAAAAAAAAAAP
"""

import re

regex = re.compile(r'^>([^\n\r]+)[\n\r]([A-Z\n\r]+)', re.MULTILINE)
matches = [m.groups() for m in regex.finditer(text)]

for m in matches:
    print 'Name: %s\nSequence:%s' % (m[0], m[1])
这将有助于:

>>> import re
>>> rx_sequence=re.compile(r"^(.+?)\n\n((?:[A-Z]+\n)+)",re.MULTILINE)
>>> rx_blanks=re.compile(r"\W+") # to remove blanks and newlines
>>> text="""Some varying text1
...
... AAABBBBBBCCCCCCDDDDDDD
... EEEEEEEFFFFFFFFGGGGGGG
... HHHHHHIIIIIJJJJJJJKKKK
...
... Some varying text 2
...
... LLLLLMMMMMMNNNNNNNOOOO
... PPPPPPPQQQQQQRRRRRRSSS
... TTTTTUUUUUVVVVVVWWWWWW
... """
>>> for match in rx_sequence.finditer(text):
...   title, sequence = match.groups()
...   title = title.strip()
...   sequence = rx_blanks.sub("",sequence)
...   print "Title:",title
...   print "Sequence:",sequence
...   print
...
Title: Some varying text1
Sequence: AAABBBBBBCCCCCCDDDDDDDEEEEEEEFFFFFFFFGGGGGGGHHHHHHIIIIIJJJJJJJKKKK

Title: Some varying text 2
Sequence: LLLLLMMMMMMNNNNNNNOOOOPPPPPPPQQQQQQRRRRRRSSSTTTTTUUUUUVVVVVVWWWWWW

关于此正则表达式的一些解释可能有用:
^(+.+?)\n\n((?:[A-Z]+\n)+)

  • 第一个字符(
    ^
    )表示“从行首开始”。请注意,它与新行本身不匹配(与$相同:它表示“刚好在新行之前”,但与新行本身不匹配)
  • 然后
    (.+?)\n\n
    表示“匹配尽可能少的字符(允许所有字符),直到到达两个换行符”。结果(不带换行符)放入第一组
  • [A-Z]+\n
    表示“匹配尽可能多的大写字母,直到到达新行。这定义了我将称之为文本行的内容。”
  • (((?:
    文本行
    )+)
    表示匹配一个或多个文本行,但不要将每一行放在一个组中。相反,将所有文本行放在一个组中
  • 如果要在末尾强制使用双换行符,可以在正则表达式中添加一个final
    \n
  • 此外,如果您不确定将得到什么类型的换行符(
    \n
    \r
    \r\n
    ),则只需通过将
    \n
    的每一次出现替换为
    (?:\n | \r\n?
    )来修复正则表达式
试试这个:

re.compile(r"^(.+)\n((?:\n.+)+)", re.MULTILINE)
我认为您最大的问题是,您希望
^
$
锚定匹配换行符,但它们不匹配。在多行模式下,
^
匹配紧跟在换行符之后的位置,
$
匹配紧跟在换行符之前的位置

还要注意,换行符可以由换行符(
\n
)、回车符(
\r
)或回车符+换行符(
\r\n
)组成。如果您不确定目标文本是否只使用换行符,则应使用此更具包容性的正则表达式版本:

re.compile(r"^(.+)(?:\n|\r\n?)((?:(?:\n|\r\n?).+)+)", re.MULTILINE)
顺便说一句,您不想在这里使用点all修饰符;您依赖的是点匹配除换行以外的所有内容。

我的首选项

lineIter= iter(aFile)
for line in lineIter:
    if line.startswith( ">" ):
         someVaryingText= line
         break
assert len( lineIter.next().strip() ) == 0
acids= []
for line in lineIter:
    if len(line.strip()) == 0:
        break
    acids.append( line )
此时,您将someVaryingText作为字符串,而acids作为字符串列表。 您可以执行
”。连接(acids)
以生成单个字符串


我发现这没有多行正则表达式那么令人沮丧(也更灵活)。

如果每个文件只有一个氨基酸序列,我根本不会使用正则表达式。就像这样:

def read_amino_acid_sequence(path):
    with open(path) as sequence_file:
        title = sequence_file.readline() # read 1st line
        aminoacid_sequence = sequence_file.read() # read the rest

    # some cleanup, if necessary
    title = title.strip() # remove trailing white spaces and newline
    aminoacid_sequence = aminoacid_sequence.replace(" ","").replace("\n","")
    return title, aminoacid_sequence

以下是匹配多行文本块的正则表达式:

import re
result = re.findall('(startText)(.+)((?:\n.+)+)(endText)',input)

除了第一行和大写文本外,文件中还有其他内容吗?我不知道为什么要使用正则表达式,而不是在换行符处拆分所有文本,并将第一个元素作为“some_variable_text”“。是的,regex是错误的工具。您的示例文本没有前导的
>
字符。应该吗?不幸的是,此正则表达式还将匹配由空行分隔的大写字母组。不过这可能没什么大不了的。看起来库恩喜欢FASTA文件如果您不希望正则表达式与任何第二行为空的文本文件相匹配,则可能需要将正则表达式中的第二个点替换为[A-Z]。-)我的印象是,目标文件将符合空行与非空行的明确(且重复)模式,因此不必指定[a-Z],但可能也不会有任何影响。此解决方案运行良好。顺便说一句,我很抱歉,因为我显然没有对情况做足够的澄清(同时也为这个答复的迟到)。谢谢你的帮助!match()只返回目标文本开头的一个匹配项,但OP表示每个文件将有数百个匹配项。我想你应该用finditer()来代替它。如果只有一种方法的话,这无疑是最简单的方法,如果添加更多的逻辑,它也可以使用更多的方法。在这个特定的数据集中大约有885种蛋白质,我觉得正则表达式应该能够处理这个问题。这是最好、最直接的答案,IMHO。