Python 文本解析 - 如何捕获和写入多行

Python text parsing - how to capture and write multiple lines

我正在尝试使用 Python 从 @ 6,500 封表单生成的电子邮件中提取某些四个数据元素:主题字段、发件人的电子邮件地址、日期戳和发件人的实际地址。

我编写了一个简单的 Python 脚本,它成功地从每条消息中复制了前三个数据元素并将它们写入一个新文件。这样做非常容易,因为对于这三个数据元素中的每一个,每个元素都有一个明确的标记("Subject"、"From" 或 "Date")。这是我的 Python 成功获取前三个数据元素的脚本:

with open("samplefile.txt") as f:
    with open("samplefileout.txt", "w") as f1:
        for line in f:
            line = line.rstrip()
            if "Subject: " in line:
                f1.write(line)
            if "From: " in line:
                f1.write(line) 
            if "Date: " in line:
                f1.write(line)

我要捕获的第四个数据元素,发件人的物理地址,处理方式不同。由于这些电子邮件的网络格式性质,发件人的姓名和家庭住址始终位于每封邮件的同一位置。以"Date:"开头的行之后有一个空行,然后下一行总是发件人的真实姓名,下一行总是发件人的家庭住址,然后总是发件人的城市和邮政编码在下一行。

我的问题是:我可以在上面的代码中添加什么,以便它不仅将 "Date:" 行写入输出文件,而且还在 "Date:"行到输出文件?我一直无法找到有关如何处理多行或相对行引用的任何信息。

第二个,相关问题。我已经开始收到第二批表单电子邮件。在第二批中,发件人的姓名和地址位于每封邮件的底部。很容易浏览并找到每条消息的开头。我如何为每条消息底部的第 1、2、3 和 4 行编写语句?对我来说,这似乎是同一类型的多行 and/or 相对行参考问题。

with open("samplefile.txt") as inf, open("samplefileout.txt", "w") as outf:
    for line in inf:
        if line.startswith("Subject: ") or line.startswith("From: "):
            outf.write(line)
        elif line.startswith("Date: "):
            outf.write(line)
            skip =     next(inf, "")    # skip blank line
            outf.write(next(inf, ""))   # 2
            outf.write(next(inf, ""))   # 3
            outf.write(next(inf, ""))   # 4

对于第二个问题,我会考虑将 inf 喂入 collections.deque(maxlen=4);当您找到消息底部时(在将其输入双端队列之前),双端队列恰好包含您想要的行。

您可以将文件读入数组,然后使用从 0 到文件长度的整数:

lines = open("test.txt").readlines()

with open("samplefileout.txt", "w") as f1:
    for x in range(0,len(lines)):
        line = lines[x].rstrip()
        if "Subject: " in line:
            f1.write(line)
        if "From: " in line:
            f1.write(line)
        if "Date: " in line:
            f1.write(line)
            f1.write(lines[x+2])
            f1.write(lines[x+3])
            f1.write(lines[x+4])

文件的最后 4 行:

lines = open("test.txt").readlines()
with open("samplefileout.txt", "w") as f1:
    end = len(lines) - 1
    f1.write(lines[end-3])
    f1.write(lines[end-2])
    f1.write(lines[end-1])
    f1.write(lines[end])