Python:正则表达式句子分割

时间:2015-11-14 02:14:04

标签: python regex

使用一个简单的tokenizer,它适用于我需要在其上显示的测试文件,在以下代码中:

import re, sys
for line in sys.stdin:
    for token in re.findall("(\w+\.\w+\.[\w.]*|\w+[-.]\w+|[-]+|'s|[,;:.!?\"%']|\w+)", line.strip()):
        print(token)

这样的文字这个房子很小。那房子很大。正确地转向:

This
house
is
small
.
That
house
is
big
.

但是,我还需要在句子之间插入一个空行:

···
small
.

That
···

所以我写了另一个循环

for token in re.sub("([\"\.!?])\s([\"`]+|[A-Z]+\w*)", "\\1\n\n\\2", line):

使用regexp几乎可以捕获我需要使用的测试文本中的所有句子中断,但是我实际上将它连接到代码时遇到了麻烦。把它放在第一个for loop里面,这对我来说最合乎逻辑,完全打破了输出。还尝试了一些if clauses,但这也无效。

3 个答案:

答案 0 :(得分:3)

使用来自nltk的{​​{3}}和sent_tokenize()组合的非正则表达式解决方案:

from nltk.tokenize import word_tokenize, sent_tokenize

s = "This house is small. That house is big."

for t in sent_tokenize(s):
    for word in word_tokenize(t):
        print(word)
    print

打印:

This
house
is
small
.

That
house
is
big
.

答案 1 :(得分:2)

这是一种更简单的方法,适用于您提供的示例。如果需要更复杂的正则表达式,可以将其添加回:

import re
mystr = "This house is small. That house is big."
for token in re.findall(r"([\w]+|[^\s])", mystr):
    print (token)
    if re.match(r"[.!?]", token):
        print()

我不太清楚你希望如何处理句子中的标点符号,以及哪个标点符号终止句子,所以它可能需要稍微修改一下。

答案 2 :(得分:0)

DetectorMorseKyle Gorman的开源句子分段,具有正式商务英语句子(WSJ文章)的最新表现。它使用简单的正则表达式作为初始过滤器,但随后使用单层感知器处理剩余的10%的困难案例。因此,它可以训练在WSJ英语以外的领域表现良好。

句子边界检测(和分割)是一个积极研究和不断完善的领域。我不认为存在可以可靠地检测句子和句子边界的正则表达式。另外,正则表达式不能轻易告诉你它们在句子边界中的“自信”程度。而且他们不能接受新的词汇,语言,方言或写作风格的再训练。我能想到的一些例子会破坏许多正则表达式:

  • 是HMTL吗? (拼写?)一种标记语言?
  • 这个怎么样...... HTML可以进一步标记。
  • 子弹句有时不会以任何特殊的标点符号结尾
  • 引用的段落如“......这句话?”。
  • Ellipses(“......”)
  • 具有特殊含义的Unicode问号和句号。
  • 人群高呼“美国的美国”。一遍又一遍。

这甚至没有开始涉及各种非正式的英语或外语语法,如克里奥尔语,聊天消息,城市俚语等。

英语(或任何自然语言)是经验定义的语言(或“历史定义”),其中语法和标点符号规则取决于人类进行交流的经验。这个经验历史“时间窗口”可以根据背景,地理位置,甚至是关于观众/读者的个人“心理理论”进行调整。甚至孩子们从小就开发自己的“秘密”语言。人类根据他们在特定领域,地理区域等中与之交流的人来制定和破坏和发展他们的语言规则。

因此,如果准确性对您很重要,那么句子分割中准确性的最新技术水平也必须是“模糊的”和经验定义的(例如机器学习)在您的领域内(一组来自“您的世界”的训练样例)。