python中的边缘情况和文本格式



作为我个人挑战的一个更大的小组项目的一部分,我正在尝试创建一个函数,将文本块格式化为两个句子块。该函数的当前形式如下:

def format_text(text):
sentences = text.split('.')    # Split up all sentences using fullstops
formatted_text = []
# In the actual code, this for loop is actually a list comprehension which looks like:
# formatted_text = ['.'.join([sentences[i-1], sentence]) + '.' for i, sentence in enumerate(sentences) if i % 2 == 1 and len(sentence) != 0]
# Testing with timeit showed it was minimally faster than the for loop.
# Any better suggestions would be well appreciated.
# However I have broken it up here as I feel the extra logic reduces it's readability.
for i, sentence in enumerate(sentences):
if i % 2 == 1:             # i.e for indexes 1, 3,... (every two sentences)
if len(sentence) != 0:    # If it isn't empty
# Append the joined sentences to result with extra fullstop (.split() removes the character it splits on)
formatted_text.append('.'.join([sentences[i-1], sentence]) + '.')
if len(sentences) % 2 == 1:    # If odd number of sentences, append final, unmatched sentence.
formatted_text.append(sentences[-1])
return formatted_text

这工作得很好。然而,在常见的口语文本中,有一些明显的情况是它失败的,以及结果不太理想的情况。以下是BBC文章节选的两个例子(https://www.bbc.co.uk/news/business-55916254):

)摘录:

但他没有得到他的好。如果你没有准备好和他见面……特别是如果你试图用流利的谈话来掩饰你缺乏准备,他会知道的,他会说得很清楚。前AWS主管斯科特·钱勒对新闻门户网站说。在这些会议上没有尽力的人不会有第二次机会,至少在很长一段时间内不会。

错误处理的两种明显方式是:

  1. 文本开头的省略号将变为:

但他没有得到他的好。"如果你没有准备好与他会面。

尤其是当你试图用花言巧语来掩盖准备不足时,

理想情况下,这应该被忽略,或者认为它是一个独立的符号。

  1. 最后一个语音标记落在两个句子的末尾,因此它最终与文本分开,实际上与:

"在这些会议上不尽力的人不会有第二次机会,至少在很长一段时间内不会。

,

理想情况下,我想保持函数小而快,但这个问题有点难倒我。我想不出一个方法不需要迭代输入字符串中的每个字符,并在每次找到句号时检查附近的字符是否有任何边缘情况。

我发现的大多数相关问题似乎要么是"我如何在所有标点符号上分割字符串"的混合,要么是如何使用正则表达式来清理不需要的文本字符串。虽然我承认几乎完全缺乏使用regex的知识,但我不知道如何使用它来忽略像省略号这样的标点符号,或者在字符串的末尾包含一个偶然的语音标记。我也见过这个问题中提到的nltk库,"https://stackoverflow.com/questions/34006169/regex-to-remove-words-from-a-list-that-are-not-a-z-a-z-exceptions/34006378#34006378",但是我不确定如何利用它来达到我的目的。

可能有一个更优雅的解决方案来解决这个问题,它利用python提供的标准函数来避免由python解释器引起的运行时缓慢。如果你有一个想法,可以帮助,或建议我在哪里可以找到一个,这将是非常感激!

我在英国,经过几个小时的研究,我非常疲惫,因为现在是凌晨1点。很抱歉,如果我错过了任何回复!

答案由MatthewMartin在对原始问题的回复中提供:

句子标记化是一个已解决的问题,参考NLTK: https://www.guru99.com/tokenize-words-sentences-nltk.html

对于处理…取代……使用ellipse或其他一些罕见的标记(或unicode for…),然后在。然后在最后,将ellipse替换为…一次。

有人会推荐使用regex, regex在机器生成文本和自然语言方面做得很好,它有它的用途,但可能不会像你希望的那样工作。例如,在真实的自然语言中,人们总是忘记句子之间的最后一个标点符号。让我们看看regex向导如何标记它。人类总是用标点或空格来标记句子,所以这不是不可能的。

答案是复制的,以防原件被删除。

最新更新