如何在Python中解析文本文件中不同数量的行?

如何在Python中解析文本文件中不同数量的行?,python,regex,parsing,text-files,Python,Regex,Parsing,Text Files,我试图编写一个简单的解析器,从一个.txt文件中获取多行文本块,并将其复制到一个新的.txt文件中。我认为我的问题不同于在线发布的类似问题的原因是,行数取决于文本块,因此我需要某种方法来确定所需文本块的开始和结束位置 考虑以下输入文件的最小示例: NAME_1{a bunch of text|more text} 1 -22.17 1 lol // 2 wtf // NA_ME2{text|text} 1 -25.50 1 gtfo // NAME3{text|text} 1 -17

我试图编写一个简单的解析器,从一个.txt文件中获取多行文本块,并将其复制到一个新的.txt文件中。我认为我的问题不同于在线发布的类似问题的原因是,行数取决于文本块,因此我需要某种方法来确定所需文本块的开始和结束位置

考虑以下输入文件的最小示例:

NAME_1{a bunch of text|more text}
 1  -22.17
1 lol //
2 wtf //
NA_ME2{text|text}
 1  -25.50
1 gtfo //
NAME3{text|text}
 1  -17.50
1 brb //
2 lol //
3 wtf //
我想让我的解析器输出一个名为_1的文本文件及其所有相关信息,名为3的文本文件及其所有相关信息。我希望输出文本文件读取:

NAME_1{a bunch of text|more text}
 1  -22.17
1 lol //
2 wtf //
NAME3{text|text}
 1  -17.50
1 brb //
2 lol //
3 wtf //
我有一个解析器,它可以工作,但是有问题而且效率低下,但是我对它还不熟悉。具体地说,我需要的大部分文本块的长度是43行,因此我的解析器识别出所需的名称,然后获取该行和接下来的42行文本。但这是一个问题,因为一些文本块的长度不是43行。这就是我到目前为止所做的:

import re

infile = open('input.txt')
outfile = open('output.txt', 'w')

# Appends all needed names into a list
nameList = []
with open('list.txt') as f:
for name in f:
    n = name.strip()
    nameList.append(n)

# Finds required name from example txt file and outputs that line and the next 42   
lines = infile.readlines()
for line in range(0,len(lines)):
    for l in nameList:
        if l in lines[line]:
         [outfile.write(part) for part in lines[line:line+42]]
list.txt文件包含以下内容:

NAME_1{
NAME3{
我认为正则表达式可以解决我的问题[A-Z]\w+{'将定位每个文本块的开头,因此我认为必须有某种方法来确定重新匹配是否等同于名称列表的一项,然后解析每一行,直到(但不包括)下一个匹配的'[A-Z]\w'+{。这样一来,一个文本块的长度就无关紧要了。是否可以用正则表达式以这种方式识别所需文本块的开始和结束位置

谢谢


编辑:每个文本块都以正则表达式“[A-Z]\w+{”的出现开始。因此,示例输入文件包含三个文本块,其中名为_1、NA_ME2和NAME3的行表示每个块的第一行。

尝试以下操作:

import re

s = """NAME_1{a bunch of text|more text}
 1  -22.17
1 lol //
2 wtf //
NA_ME2{text|text}
 1  -25.50
1 gtfo //
NAME3{text|text}
 1  -17.50
1 brb //
2 lol //
3 wtf //
"""

guards = ["NAME_1", "NAME3"]    
r = re.compile(r"^([A-Z][A-Z0-9_]+){")
printing = False

for line in s.splitlines():
    m = r.match(line)
    if m:
        if m.groups(1) and m.groups(1)[0] in guards:
            printing = True
        else:
            printing = False
    if printing:
        print(line.strip())
输出:

NAME_1{a bunch of text|more text}
1  -22.17
1 lol //
2 wtf //
NAME3{text|text}
1  -17.50
1 brb //
2 lol //
3 wtf //

块何时结束?每个文本块都以正则表达式“[a-Z]\w”的每次出现开始+{'。换句话说,在我的示例文本文件中,NAME_1是第一个块的开始,NA_ME2是第二个块的开始,NAME3是第三个块的开始。因此,您可以通过匹配此正则表达式来标识每个块。如果该块是您感兴趣的块之一,则输出它。如果不是,则继续,直到到达下一个感兴趣的块。LogiCaly这对我来说是有意义的,但我只是一个开始,正在寻求如何做到这一点的建议。我已经搜索stackoverlow几个小时了,无法解决我的问题。感谢Lutz,非常感谢您的帮助!抱歉,有一个简短的后续问题。我已经将input.txt文件作为字符串读入Python,以代替您的变量,并替换了printline、 带outfile.writeline.strip的strip命令,其中outfile=open'output.txt',w'。虽然这会解析所需的输出文本,但它会在一行中输入output.txt。所有内容都在一行中是因为strip吗?我想如果留空,它只会删除空白。经过大量的努力,我解决了我的问题。似乎分割线导致了p问题,再次感谢!