【问题标题】:How can I merge together sentence objects?如何将句子对象合并在一起?
【发布时间】:2013-06-21 22:05:22
【问题描述】:

所以我构建了一个句子标记器,它将段落分成句子、单词和字符……每一个都是一种数据类型。但是句子系统是一个两阶段系统,因为像'。 . 。把它扔掉,感觉它一次只写一个字母,但如果它是 '...' 没有空格,它就可以正常工作。

所以输出有点拼接,但如果我可以对其进行一些二次处理,它会完美地工作。所以这就是我的问题所在......我不知道如何编写一个系统,允许我将每个没有结束句标点符号的句子附加到前一个句子而不会丢失任何东西。

以下是输出的示例以及我需要的示例:

一些被拼接的句子……

还有一个延续

这不能被美国混淆

在那个

最后一句话……

一个缩写结束了句子!

所以句子对象不以正常的句尾分隔符结尾,即'.'、'?'、'!'需要附加到下一个句子......直到有一个带有真正句尾分隔符的句子。让这变得艰难的另一件事是'。 . 。算作一个延续,而不是一个句子的结尾。所以这也需要附加。

应该是这样的:

一些被拼接的句子......并且有一个延续。

这不能被美国混淆

在最后一句话中……一个缩写词结束了这句话!

这是我正在使用的代码:

 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. 它只将1个句子附加到另一个句子,但如果有2个或3个需要添加,它不会继续附加。

  2. 如果第一个句子中没有任何标点符号,它会删除它。

  3. 它不处理'. . 。作为延续。我知道我没有为此写任何东西,那是因为我不完全确定如何解决这个问题,句子以缩写结尾,因为我可以数出有多少'。在句子中,但它真的会被“U.S.A.”抛弃因为这算作3个时期。

所以我已经为句子类编写了一个__add__ 方法,因此您可以执行sentence + sentence 并且这是一种将一个附加到另一个的方法。

对此的任何帮助将不胜感激。如果有任何不清楚的地方,请告诉我,我会尽我最大的努力去实现它。

【问题讨论】:

  • 你能递归地阐明你想要什么吗?你想要一个递归函数还是任何可以完成这项工作的东西?
  • 它不一定需要是隐性的......但我可能用这个词太松了......我的意思是我不希望它继续合并相同的感觉直到它得到一个真正的感觉突破。这样做的方法不必是隐性的。我已经更新了标题,以免误导。
  • @WoLpH 我认为他指的是牙龈萎缩
  • +1 用于广泛的问题并提供信息顺便说一句:)
  • @WoLpH 谢谢...我正在构建您的代码。你有正确的想法。我只需要修改它以在我的类结构中工作。非常感谢您的宝贵时间。

标签: python algorithm object append


【解决方案1】:

这个“算法”试图在不依赖行尾的情况下理解输入,因此它应该在某些输入上正常工作,例如

born in the U.
S.A.

代码适合集成到状态机中 - 循环仅记住其当前短语并将完成的短语“推送”到列表中,并一次吞下一个单词。分割空格很好。

请注意案例 #5 中的歧义:无法可靠地解决(而且行尾也可能存在这种歧义。也许结合 both...)

# 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!

【讨论】:

  • 非常感谢您抽出宝贵时间帮助我。我会玩弄你的代码。再次非常感谢。
【解决方案2】:

好的,这里有一些工作代码。这大致是你需要的吗? 我还不太满意,它看起来有点丑恕我直言,但我想知道它是否是正确的方向。

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!

【讨论】:

  • 它会起作用,但是......也许我对此有点不清楚,但我使用的是类结构......因为有一个字符类,一个单词类和一个句子类,并且由于这种层次结构,它给系统带来了一些困难。一种是您可以追加的唯一方法是使用 + 运算符。但除此之外,我相信你走在正确的轨道上。我非常感谢您的帮助。这是句子数据类型的示例:[<__main__.character object at>, <__main__.character object at>].. 它基本上是一个字符列表。
  • 我必须保留 char 对象而不只是让这件事变得更简单的原因是因为我正在用它解析 EPUB 文档并且我必须保持 html 完整,所以为了这样做我必须建立一个类结构。
  • 当你的代码工作得很好......也许我可以尝试对其进行某种修改以与我的系统一起使用。非常感谢您的帮助。
  • @AlexW.H.B.:我已经稍微更新了答案,现在更漂亮了:)
【解决方案3】:

这是我最终使用的代码,效果很好……这主要基于 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2014-05-01
    • 2018-11-23
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多