【问题标题】:Python: Extracting Sentences From Line - Regex Needed Based on CriteriaPython:从行中提取句子 - 需要基于标准的正则表达式
【发布时间】:2014-01-08 19:58:31
【问题描述】:

这里有点python/编程新手...

我正在尝试提出一个正则表达式,它可以处理从文本文件中的一行中提取句子,然后将它们附加到列表中。代码:

import re

txt_list = []

with open('sample.txt', 'r') as txt:
    patt = r'.*}[.!?]\s?\n?|.*}.+[.!?]\s?\n?'
    read_txt = txt.readlines()

    for line in read_txt:
        if line == "\n":
            txt_list.append("\n")
        else: 
            found = re.findall(patt, line)
            for f in found:
                txt_list.append(f)


for line in txt_list:
    if line == "\n":
        print "newline"
    else:
        print line

根据上述代码的最后 5 行打印输出:

{Hello there|Hello|Howdy} Dr. Munchauson you {gentleman|fine fellow}! 
What {will|shall|should} we {eat|have} for lunch? Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said.

newline
I am the {very last|last} sentence for this {instance|example}.

'sample.txt'的内容:

{Hello there|Hello|Howdy} Dr. Munchauson you {gentleman|fine fellow}! What {will|shall|should} we {eat|have} for lunch? Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said.

I am the {very last|last} sentence for this {instance|example}.

我已经玩了几个小时的正则表达式,但我似乎无法破解它。就目前而言,正则表达式在for lunch? 的末尾不匹配。因此这两个句子What {will|shall|should} we {eat|have} for lunch? Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said. 没有分开;这就是我想要的。

正则表达式的一些重要细节:

  • 每个句子总是以句号、感叹号或问号结尾
  • 每个句子将始终包含至少一对大括号“{}”,其中包含一些单词。也不会有误导性的“。”在每个句子的最后一个括号之后。因此Dr. 将始终位于每个句子中的最后一对大括号之前。这就是为什么我试图围绕使用'}'来建立我的正则表达式。这样我可以避免使用异常方法,为Dr.Jr.approx. 等语法创建异常。对于我运行此代码的每个文件,我个人确保在任何句子的最后一个“}”之后没有“误导性句点”。

我想要的输出是这样的:

{Hello there|Hello|Howdy} Dr. Munchauson you {gentleman|fine fellow}! 
What {will|shall|should} we {eat|have} for lunch?
Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said.

newline
I am the {very last|last} sentence for this {instance|example}.

【问题讨论】:

  • 在此“{Hello there|Hello|Howdy} Dr. Munchauson 你{绅士|好人}!”有误导性的“。”这里。第一个句点也在这个“句子”的最后一个括号之后:“{Hello there|Hello|Howdy} Dr.”
  • 在那句话中,'!'是句子的结尾,而“!”出现在该句子中的最后一个“}”之后。正如我在 OP 中解释的那样,句子可以以句号、感叹号或问号结尾。

标签: python regex


【解决方案1】:

如果您不介意添加依赖项,NLTK 库有一个 sent_tokenize 函数应该可以满足您的需求,但我不完全确定大括号是否会干扰。

描述 NLTK 使用的方法的论文长达 40 多页。检测句子边界并非易事。

【讨论】:

  • 谢谢。我知道sent_tokenize 存在,尽管我还没有尝试过。我希望让我的脚本在大括号和正则表达式的后面工作,但看起来它没有发生。我刚刚在几个包含这些大括号的文件上尝试了sent_tokenize,它准确地分割了所有句子,所以我想我会坚持下去。它不会以我想要的方式保留换行符,但我可以为此编写一些代码。干杯
  • 您可以将每一行分别提供给sent_tokenize,而不是对整个文本块进行标记。只要您不希望句子超出源文件中的一行,那应该可以让您以您想要的方式保留换行符。
【解决方案2】:

我得到的最直观的解决方案就是这个。从本质上讲,您需要将Dr.Mr. 标记本身视为原子。

patt = r'(?:Dr\.|Mr\.|.)*?[.!?]\s?\n?'

分解,它说:

找到最少的Mr.s、Dr.s 或任何字符,直到一个标点符号后跟一个零或一个空格,然后是零个或一个新行。

在这个sample.txt上使用时(我加了一行):

{Hello there|Hello|Howdy} Dr. Munchauson you {gentleman|fine fellow}! What {will|shall|should} we {eat|have} for lunch? Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said.

But there are no {misters|doctors} here good sir! Help us if there is an emergency.

I am the {very last|last} sentence for this {instance|example}.

它给出:

{Hello there|Hello|Howdy} Dr. Munchauson you {gentleman|fine fellow}!
What {will|shall|should} we {eat|have} for lunch?
Peas by the {thousand|hundred|1000} said Dr. Munchauson; {that|is} what he said.

newline
But there are no {misters|doctors} here good sir!
Help us if there is an emergency.

newline
I am the {very last|last} sentence for this {instance|example}.

【讨论】:

  • 您好,我真的希望避免以这种方式使用异常,因为我将在许多文本文件上运行此代码。所以可能会有很多例外,例如Sr.approx.info.e.t.c 等等。我现在唯一可以确定的是,每个句子中最后一个右大括号} 之后不会有. - 当然除非. 实际上是句子的结尾。
  • 我不认为你可以有一个通用的。您可以说最后一个大括号之后的唯一句点不是缩写,但是正则表达式如何知道} Dr. } said. 之间的区别?它们都是字母后跟一个句点。我们可以说前者有一个大写字母,但这排除了approx.info.e.t.c 等......如果不在句子中声明什么是“有效”句点,我认为你做不到你在问什么。
  • 我明白了,我希望我的正则表达式技能还不足以完成这项任务。好的,我想我会屈服于实质性例外方法。感谢您的帮助:-)
  • 由于这个答案和@aelfric5578 给出的答案都非常有用,因此很难确定将哪个答案标记为已接受。基本上我都接受他们。但是我必须选择这个,因为它确定正则表达式不起作用。
猜你喜欢
  • 2012-12-19
  • 2015-03-12
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 2021-12-24
  • 2011-01-04
相关资源
最近更新 更多