使用一个简单的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
,但这也无效。
答案 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)
DetectorMorse是Kyle Gorman的开源句子分段,具有正式商务英语句子(WSJ文章)的最新表现。它使用简单的正则表达式作为初始过滤器,但随后使用单层感知器处理剩余的10%的困难案例。因此,它可以训练在WSJ英语以外的领域表现良好。
句子边界检测(和分割)是一个积极研究和不断完善的领域。我不认为存在可以可靠地检测句子和句子边界的正则表达式。另外,正则表达式不能轻易告诉你它们在句子边界中的“自信”程度。而且他们不能接受新的词汇,语言,方言或写作风格的再训练。我能想到的一些例子会破坏许多正则表达式:
这甚至没有开始涉及各种非正式的英语或外语语法,如克里奥尔语,聊天消息,城市俚语等。
英语(或任何自然语言)是经验定义的语言(或“历史定义”),其中语法和标点符号规则取决于人类进行交流的经验。这个经验历史“时间窗口”可以根据背景,地理位置,甚至是关于观众/读者的个人“心理理论”进行调整。甚至孩子们从小就开发自己的“秘密”语言。人类根据他们在特定领域,地理区域等中与之交流的人来制定和破坏和发展他们的语言规则。
因此,如果准确性对您很重要,那么句子分割中准确性的最新技术水平也必须是“模糊的”和经验定义的(例如机器学习)在您的领域内(一组来自“您的世界”的训练样例)。