散文中的分裂句子

时间:2018-04-11 16:44:27

标签: python regex parsing text nlp

我试图分开句子,并保留对话标记。所以像

这样的句子
  琼斯先生,“肮脏的?”看看我的鞋子!不是他们的特色。“这是一个非对话的句子!

应该返回列表

[
    "“Dirty, Mr. Jones?”",
    "“Look at my shoes!”",
    "“Not a speck on them.”",
    "This is a non-dialogue sentence!"
]

我正努力保留句末标点符号,同时保留Mr.上的句号。我也在努力插入引号,因为目前返回的列表是['“Dirty, Mr. Jones”', '“Look at my shoes”', '“Not a speck on them”', '“”', 'This is a non-dialogue sentence', ''],我不知道为什么我得到两个空元素。我该如何解决这些问题?

这是我的代码(最终这将解析整本书,但现在我正在测试一个短语):

def get_all_sentences(corpus):

  sentences_in_paragraph = []

  dialogue = False
  dialogue_sentences = ""
  other_sentences = ""

  example_paragraph = "“Dirty, Mr. Jones? Look at my shoes! Not a speck on them.”  This is a non-dialogue sentence!"

  example_paragraph = example_paragraph.replace("\n", "") # remove newline

  for character in example_paragraph:
    if character == "“":
        dialogue = True
        continue
    if character == "”":
        dialogue = False
        continue

    if dialogue:
        dialogue_sentences += character
    else:
        other_sentences += character

  sentences_in_paragraph  = list(map(lambda x: "“" + x.strip() + "”", re.split("(?<!Mr|Ms)(?<!Mrs)[.!?]", dialogue_sentences))) 
  sentences_in_paragraph += list(map(lambda x: x.strip(), re.split("(?<!Mr|Ms)(?<!Mrs)[.!?]", other_sentences)))

  print(sentences_in_paragraph)

1 个答案:

答案 0 :(得分:1)

如果您添加print语句以显示中间步骤,则可以查看问题的引入位置:

sentence_splitter_regex = "(?<!Mr|Ms)(?<!Mrs)[.!?]"
dialogue_sentences_list = re.split(sentence_splitter_regex, dialogue_sentences)
print("dialogue sentences:", dialogue_sentences_list)
other_sentences_list = re.split(sentence_splitter_regex, other_sentences)
print("other sentences:", other_sentences_list)

sentences_in_paragraph  = list(map(lambda x: "“" + x.strip() + "”", dialogue_sentences_list)) 
sentences_in_paragraph += list(map(lambda x: x.strip(), other_sentences_list))
dialogue sentences ['Dirty, Mr. Jones', ' Look at my shoes', ' Not a speck on them', '']
other sentences ['    This is a non-dialogue sentence', '']

re.split在末尾留下一个空元素。您可以通过使用带有for子句的if理解处理结果来解决此问题,以便不包含空字符串:

[sentence for sentence in sentences_with_whitespace if sentence.strip() != '']

您应该将此代码放在新函数split_sentences_into_list中,以保持代码的有序性。通过将.strip()理解的第一部分更改为get_all_sentences,将for处理从sentence.strip()移到此函数中也是有意义的。

import re

def split_sentences_into_list(sentences_string):
    sentence_splitter_regex = "(?<!Mr|Ms)(?<!Mrs)[.!?]"
    sentences_with_whitespace = re.split(sentence_splitter_regex, sentences_string)
    return [sentence.strip() for sentence in sentences_with_whitespace if sentence.strip() != '']

def get_all_sentences(corpus):
    sentences_in_paragraph = []

    dialogue = False
    dialogue_sentences = ""
    other_sentences = ""

    example_paragraph = "“Dirty, Mr. Jones? Look at my shoes! Not a speck on them.”    This is a non-dialogue sentence!"

    example_paragraph = example_paragraph.replace("\n", "") # remove newline

    for character in example_paragraph:
        if character == "“":
            dialogue = True
            continue
        if character == "”":
            dialogue = False
            continue

        if dialogue:
            dialogue_sentences += character
        else:
            other_sentences += character

    dialogue_sentences_list = split_sentences_into_list(dialogue_sentences)
    other_sentences_list = split_sentences_into_list(other_sentences)

    sentences_in_paragraph  = list(map(lambda x: "“" + x + "”", dialogue_sentences_list)) 
    sentences_in_paragraph += other_sentences_list

    print(sentences_in_paragraph)

get_all_sentences(None)

这有预期的输出:

['“Dirty, Mr. Jones”', '“Look at my shoes”', '“Not a speck on them”', 'This is a non-dialogue sentence']

顺便说一下,标准Python样式是尽可能使用for理解而不是maplambda。在这种情况下,它会使您的代码更短:

# from
sentences_in_paragraph  = list(map(lambda x: "“" + x + "”", dialogue_sentences_list)) 
# to
sentences_in_paragraph  = ["“" + x + "”" for x in dialogue_sentences_list]