【问题标题】:How to extract the part of a text file after the second occurrence of a specific word using Python如何使用Python在第二次出现特定单词后提取文本文件的一部分
【发布时间】:2020-06-24 23:42:37
【问题描述】:

我试图在第二次出现特定单词之后提取文本文件的一部分,直到再次出现另一个特定单词为止。原因是在目录中首先说明了这两个词。因此,当我运行代码时,第一次出现的输出为 0。

示例文本:

目录

项目 1a.风险因素

  • 没有任何文字(不需要的部分)

项目 1b

目录结束

主要内容
第 1a 项。风险因素

  • 文本(需要的部分)
  • 文本(需要的部分)
  • 文本(需要的部分)

项目 1b

我需要在第 1a 项的第二次出现之间提取文本。风险因素和第 1b 项的第二次出现。

我的代码如下:

for file in tqdm(files):
with open(file, encoding='ISO-8859-1') as f:
    for line in f:
        if line.strip() == 'Item 1A.Risk Factors': 
            break
    for line in f: 
        if line.strip() == 'Item 1B':
            break
f=open(os.path.join('QTR4_Risk_Factors',
os.path.basename(file)) , 'w')
f.write(line)
f.close()

【问题讨论】:

  • 是否要返回第二次出现Item 1a. Risk Factors 之后和Item 1a. Risk Factors 之后第一次 出现Item 1b 之前的文本?如果是这样,那不是你要求的。在您的示例中,第一个 Item 1b 在第一次出现 Item 1a. Risk Factors 之前,但如果 Item 1b 没有在 Item 1a. Risk Factors 之前,我们将在 Item 1a. Risk Factors 之后寻找第二次出现 Item 1b
  • 我只想提取第二次出现的 Item1A 和第二次出现的 Item 1B 之间的文本部分。
  • 如果Item 1b 的第二个实例出现在Item 1a 的第一个实例之前,您希望返回一个空字符串(或某种失败)。你选择的答案是这样吗?

标签: python regex text extract analysis


【解决方案1】:

您编写的代码几乎没有问题,其中一个是您在扫描文档以查找“结束文本”时没有保存所需的文本部分。此外,如果可能,最好在内存中存储尽可能少的文本,因为我们不知道您要分析的文档有多大。为此,我们可以在读取原始文件的同时写入新文件。

Ronie 的回答是朝着正确的方向发展,但它没有解决您只想在“开始提示”第二次出现后才开始保存文本的事实。不幸的是,我还无法评论建议编辑,所以我将其添加为新答案。 试试这个:

for file in tqdm(files):
    with open(file, encoding='ISO-8859-1') as f, open(os.path.join('QTR4_Risk_Factors', os.path.basename(file)) , 'w') as w:
        start_hint_counter = 0
        write = False
        for line in f:
            if write is False and line.strip() == 'Item 1A.Risk Factors': 
                start_hint_counter += 1
                if start_hint_counter == 2:
                    write = True
            if write is True:
                if line.strip() == 'Item 1B':
                    break
                else:
                    w.write(line)

【讨论】:

  • 非常感谢您的回答。代码运行正常。我有另一个与此相关的问题。在某些文件中,有 Item 1B,有些则没有,它在 Item 2 之后。如何将这种情况添加到代码中?
  • @volkanarslan 一种天真的方法是简单地为 if 添加更多条件。 if line.strip() == 'Item 1B': 可以变成 if line.strip() == 'Item 1B or line.strip() == 'Item 2': 如果你想添加更多选项,可以有更好的方法。
  • 效果很好。最后一个问题:) 如果只有“项目 1B”或“项目 2”,此代码会显示行,它会停止。但如果Item 2.XXX等关键字后面还有其他文字,则继续提取。再次感谢
  • 如果您想在行首查找内容,可以使用if line.startswith('Item 1B'),或者更通用的是if 'Item 1B' in line。看看Python reference documentation on string manipulation,很有用
【解决方案2】:

我认为您应该制作一个标志以知道何时复制这些行。您还可以在上下文管理器中同时打开 2 个或更多文件。

with open(file, encoding='ISO-8859-1') as f, open(os.path.join('QTR4_Risk_Factors', os.path.basename(file)) , 'w') as w:
    write = False
    for line in f:
        if line.strip() == 'Item 1A.Risk Factors': 
            write = True
            continue
        elif line.strip() == 'Item 1B':
            write = False
        if write == True:
            w.write(line)

Ronie 的回答是朝着正确的方向发展,但它没有解决您只想在“开始提示”第二次出现后才开始保存文本的事实。

编辑:添加continue

【讨论】:

  • 谢谢。现在它开始从“项目 1A”的第 1 次出现直到第 1B 项的第 2 次出现。
【解决方案3】:

你可以试试正则表达式:

import re

t = """Item 1a.Risk Factors

not any text (unwanted portion)
Item 1b

End of table of contents

Main content
Item 1a. Risk Factors

text (wanted portion)
text (wanted portion)
text (wanted portion)
Item 1b"""

crit = re.compile('Item 1a.Risk Factors.*?Item 1a. Risk Factors(.*?)Item 1b', re.I|re.DOTALL)
if re.search(crit, t):
    result = re.search(crit, t).group(1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 2021-10-15
    • 2014-10-18
    • 1970-01-01
    相关资源
    最近更新 更多