【问题标题】:Edge cases and text formatting in pythonpython中的边缘情况和文本格式
【发布时间】:2021-02-08 01:12:20
【问题描述】:

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

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 主管 Scott Chancellor 告诉新闻门户。 “在这些会议中没有尽最大努力的人不会得到第二次机会,至少在很长一段时间内不会。”

这将被错误处理的两种值得注意的方式是:

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

但他并没有因为友善而到达现在的位置。 “如果你还没有准备好与他会面。

尤其是如果你试图用流畅的谈话来掩盖准备不足的情况,

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

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

“在这些会议中没有尽全力的人不会得到第二次机会,至少在很长一段时间内不会。

"

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

我发现的大多数相关问题似乎都是“如何在所有标点符号处拆分字符串”或如何使用正则表达式来清除不需要的文本字符串的混合。虽然我承认几乎完全缺乏使用正则表达式的知识,但我不知道有什么方法可以使用它来忽略像省略号这样的标点符号,或者在字符串末尾包含一个杂散的语音标记。我还看到了这个问题中提到的 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 点,我已经筋疲力尽了。很抱歉,如果我错过任何回复!

【问题讨论】:

  • 句子标记是一个已解决的问题,参考 NLTK:guru99.com/tokenize-words-sentences-nltk.html
  • 对于处理 ... 用 ELIPSE 或其他一些稀有令牌(或 unicode 为 ...)替换 ... 的特殊方式,然后在 .然后在最后,再次用 ... 替换 ELIPSE。
  • 有人会推荐使用正则表达式,正则表达式在机器生成的文本和自然语言方面做得非常好,它有它的用途,但可能不会像你希望的那样工作。例如,在真正的自然语言中,人们总是忘记句子之间的最后标点符号。让我们看看正则表达式向导对其进行了标记。人类一直在标记不带点或空格的句子,所以这并非不可能。
  • 感谢您的回复!我会看看你发送的那个链接,你的第二个回复听起来对我来说是个不错的方法。您介意将此添加为答案,以便我将其标记为这样吗?

标签: python python-3.x


【解决方案1】:

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

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

对于处理 ... 的特殊方式,将 ... 替换为 ELIPSE 或其他一些稀有令牌(或 unicode 为 ...),然后在 .然后在最后,再次将 ELIPSE 替换为 ...。

有人会推荐使用正则表达式,正则表达式在机器生成的文本和自然语言方面做得非常好,它有它的用途,但可能不会像你希望的那样有效。例如,在真正的自然语言中,人们总是忘记句子之间的最后标点符号。让我们看看正则表达式向导对其进行了标记。人类一直在标记不带点或空格的句子,所以这并非不可能。

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

【讨论】:

  • 您需要在问题本身中包含所有相关内容。如果评论被删除,那么这个答案是没有用的。然后您可以将自己的答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多