【问题标题】:Extract text between any combination of expressions (list)提取任意表达式组合之间的文本(列表)
【发布时间】:2024-05-29 17:10:02
【问题描述】:

我需要从文本文件(嵌入在较大文件中的字母的开头和结尾)中提取两个表达式(开头和结尾)之间的文本。我面临的问题是,字母的开头和结尾都有多种可能的表达方式。

我有一个表达式列表,可能有资格作为开始/结束表达式。我需要从较大的文本(包括开头和结尾表达式)中提取这些表达式的任意组合之间的所有文本,并将其写入一个新文件。

sample_text = """Some random text 
asdasd
asdasd
asdasd
**Dear my friend,
this is the text I want to extract.
Sincerly,
David**
some other random text
adasdsasd"""

到目前为止我的代码:

letter_begin = ["dear", "to our", "estimated", ...]
letter_end = ["sincerly", "yours", "best regards", ...]

with open('path/to/input') as infile, open('path/to/output', 'w') as outfile:
    copy = False
    for line in infile:
        if line.strip() == "dear": #shortcomming: only 1 Expression possible here
            copy = True
        elif line.strip() == "sincerly": #shortcomming: only 1 Expression possible here
            copy = False
        elif copy:
            outfile.write(line)

上面的例子包括“Dear”作为 letter_begin 表达式和“Sicerly”作为 letter_end 表达式。我需要一个灵活的代码,它能够从上面的列表中捕获任何开头和结尾的字母表达式(表达式的任何潜在组合;例如“亲爱的 [...] 休息”或“估计 [...]真诚的”)

【问题讨论】:

  • 你真正想从上面的文本中提取什么?
  • 嗨,蒂姆,我想提取“亲爱的朋友,这是我要提取的文本。真诚的,大卫”,其中“亲爱的”表示开始,“真诚”表示结束字母 - 开头和结尾的标识必须灵活,因为我想遍历一堆文件(具有不同的开头和结尾表达式)
  • 所以你只想提取一个包含Dear my friend行,对吗?
  • 不,我想提取从“亲爱的”开始到“真诚”结束的所有文本 [+ 之后的单词,这是名字”。从上面的示例中,所需的输出将是“亲爱的我朋友,这是我要提取的文字。此致,大卫”

标签: python regex text-mining text-extraction


【解决方案1】:

我们可以尝试在全点和多行模式下使用re.findall,模式如下:

Dear\s+.*?Sincerely,\n\S+

这将捕获并包括从单词Dear 到包括Sincerely 在内的所有内容,然后是Sincerely 之后的下一行之后的所有内容。这是一个代码示例:

output = re.findall(r"Dear\s+.*?Sincerely,\n\S+", sample_text, re.MULTILINE|re.DOTALL)
print(output)

编辑:

如果你想匹配多个可能的问候和结束,那么我们可以使用交替:

letter_begin = ["dear", "to our", "estimated"]
openings = '|'.join(letter_begin)
print(openings)
letter_end = ["sincerely", "yours", "best regards"]
closings = '|'.join(letter_end)
regex = r"(?:" + openings + r")\s+.*?" + r"(?:" + closings + r"),\n\S+"
output = re.findall(regex, sample_text, re.MULTILINE|re.DOTALL|re.IGNORECASE)
print(output)

['Dear my friend,\nthis is the text I want to extract.\nSincerely,\nDavid**']

【讨论】:

  • 非常感谢蒂姆的解决方案。如果我做对了,那么这个解决方案仅适用于“亲爱的”和“真诚的”这两个表达方式,但不会捕捉到任何其他表达的开头(例如“估计的朋友”)或结尾(例如“最好的问候”)这封信,对吗?
  • 是的,没错。如果您有其他逻辑,我可以编辑我的答案。通常,要使用正则表达式,您需要对要匹配的文本有所了解。正则表达式不能真正进行机器学习,也不能猜测内容。
  • 好的,有没有办法告诉正则表达式搜索任何出现的表达式列表(在本例中为 letter_begin 列表)并“记录”从这次出现到出现的所有文本来自其他列表(在本例中为 letter_end 列表)的表达式?
  • 是的,我们可以使用替代方法。编辑您的问题,并提供必要的信息。我发布的内容回答了您的实际问题。
  • @DominikScheld 答案已更正,here is a demo 你可以试试。