所以我构建了一个句子标记器,它将段落分成句子,单词和字符......每个都是数据类型。但句子系统是一个两阶段系统,因为像'。 。 “。把它扔掉,感觉它一次只能写一个字母,但是如果它是'......'没有空格,它就能正常工作。
因此输出有点拼接,但如果我可以对它进行一些二次处理,它将完美地工作。所以这就是我的问题所在...我不知道如何编写一个系统,允许我将没有结束句点标点的每个句子附加到前一句,而不会丢失一些东西。
以下是输出结果的示例以及我需要它的样子:
一些被拼接的句子......
并有一个延续
这不能被美国混淆。
在那
最后一句......
缩写结束了句子!
所以句子对象不以正常的句末分隔符结尾,即'。','?','!'需要附加到下一句...直到有一个句子带有真正的句子分隔符。另一件使这件事变得艰难的事情就是'。 。 “。算作延续,而不是句子的结尾。所以这也需要附加。
这就是它需要的方式:
一些被拼接的句子......并且有一个延续。
这不能被美国混淆。
在最后一句话中......缩写结束了句子!
这是我正在使用的代码:
last = []
merge = []
for s in stream:
if last:
old = last.pop()
if '.' not in old.as_utf8 and '?' not in old.as_utf8 and '!' not in old.as_utf8:
new = old + s
merge.append(new)
else:
merge.append(s)
last.append(s)
因此这种方法存在一些问题...
它只会将1个句子附加到另一个句子,但如果有2个或3个需要添加,则不会继续追加。
如果第一句中没有任何标点符号,则会删除第一句。
它没有处理'。 。 “。作为延续。我知道我在这方面没有做任何事情,那是因为我不完全确定如何解决这个问题,句子以缩写结尾,因为我可以计算多少'。'在句子中,但它会被'U.S.A'真的抛弃。因为这算作3个时期。
因此我在句子类中编写了一个__add__
方法,因此您可以执行sentence + sentence
,这样可以将一个方法附加到另一个方法。
任何帮助都会对此非常感激。如果有任何不清楚之处,请告诉我,我会尽力安排它。
答案 0 :(得分:2)
这个'算法'尝试在不依赖行结尾的情况下理解输入,因此应正确地使用某些输入
born in the U.
S.A.
该代码有助于集成到状态机中 - 循环仅记住其当前短语并将完成的短语“推送”到列表中,并且一次吞噬一个单词。拆分空格很好。
注意案例#5中的歧义:无法可靠地解决(并且也可能在行结尾处存在这种歧义。也许组合两者 ...)
# Sample decoded data
decoded = [ 'Some', 'sentence', 'that', 'is', 'spliced.', '.', '.',
'and', 'has', 'a', 'continuation.',
'this', 'cannot', 'be', 'confused', 'by', 'U.', 'S.', 'A.', 'or', 'U.S.A.',
'In', 'that', 'last', 'sentence...',
'an', 'abbreviation', 'ended', 'the', 'sentence!' ]
# List of phrases
phrases = []
# Current phrase
phrase = ''
while decoded:
word = decoded.pop(0)
# Possibilities:
# 1. phrase has no terminator. Then we surely add word to phrase.
if not phrase[-1:] in ('.', '?', '!'):
phrase += ('' if '' == phrase else ' ') + word
continue
# 2. There was a terminator. Which?
# Say phrase is dot-terminated...
if '.' == phrase[-1:]:
# BUT it is terminated by several dots.
if '..' == phrase[-2:]:
if '.' == word:
phrase += '.'
else:
phrase += ' ' + word
continue
# ...and word is dot-terminated. "by U." and "S.", or "the." and ".".
if '.' == word[-1:]:
phrase += word
continue
# Do we have an abbreviation?
if len(phrase) > 3:
if '.' == phrase[-3:-2]:
# 5. We have an ambiguity, we solve using capitals.
if word[:1].upper() == word[:1]:
phrases.append(phrase)
phrase = word
continue
phrase += ' ' + word
continue
# Something else. Then phrase is completed and restarted.
phrases.append(phrase)
phrase = word
continue
# 3. Another terminator.
phrases.append(phrase)
phrase = word
continue
phrases.append(phrase)
for p in phrases:
print ">> " + p
输出:
>> Some sentence that is spliced... and has a continuation.
>> this cannot be confused by U.S.A. or U.S.A.
>> In that last sentence... an abbreviation ended the sentence!
答案 1 :(得分:1)
好的,这是一些有效的代码。这大致是你需要的吗? 我对它不太满意,它看起来有点丑陋imho但是我想知道它是否是正确的方向。
words = '''Some sentence that is spliced...
and has a continuation.
this cannot be confused by U.S.A.
In that
last sentence...
an abbreviation ended the sentence!'''.split()
def format_sentence(words):
output = []
for word in words:
if word.endswith('...') or not word.endswith('.'):
output.append(word)
output.append(' ')
elif word.endswith('.'):
output.append(word)
output.append('\n')
else:
raise ValueError('Unexpected result from word: %r' % word)
return ''.join(output)
print format_sentence(words)
输出:
Some sentence that is spliced... and has a continuation.
this cannot be confused by U.S.A.
In that last sentence... an abbreviation ended the sentence!
答案 2 :(得分:0)
这是我最终使用的代码,它工作得很好......这主要基于WoLpH代码,所以非常感谢你!
output = stream[:1]
for line in stream:
if output[-1].as_utf8.replace(' ', '').endswith('...'):
output[-1] += line
elif not output[-1].as_utf8.replace(' ', '').endswith('.') and not output[-1].as_utf8.replace(' ', '').endswith('?') and not output[-1].as_utf8.replace(' ', '').endswith('!') and not output[-1].as_utf8.replace(' ', '').endswith('"') and not output[-1].as_utf8.replace(' ', '')[-1].isdigit():
if output[-1] != line:
output[-1] += line
else:
if output[-1] != line:
output.append(line)
return output