获取整个Unicode句子

2 投票
2 回答
871 浏览
提问于 2025-04-17 03:45

我正在尝试解析一个句子,比如 Base: Lote Numero 1, Marcelo T de Alvear 500. Demanda: otras palabras. 我想做的是:首先,把文本按句号分开,然后,把冒号前面的部分当作后面句子的 标签

from pyparsing import *

unicode_printables = u''.join(unichr(c) for c in xrange(65536) 
                                    if not unichr(c).isspace())

def parse_test(text):
    label = Word(alphas)+Suppress(':')
    value = OneOrMore(Word(unicode_printables)|Literal(','))
    group = Group(label.setResultsName('label')+value.setResultsName('value'))
    exp = delimitedList(
        group,
        delim='.'
    )

    return exp.parseString(text)

现在我有了以下的定义:

这个方法有点效果,但它把一些特殊字符(还有那些不是字母或数字的东西)给去掉了。我希望能把 保留为完整的句子,而不是现在这样:'value': [(([u'Lote', u'Numero', u'1', ',', u'Marcelo', u'T', u'de', u'Alvear', u'500'], {}), 1)

有没有简单的方法来解决这个问题呢?

2 个回答

1

你可以看看 PyICU 这个工具,它可以让你使用ICU提供的强大Unicode文本库。里面有一个叫 BreakIterator 的类,可以帮助你找到句子。

2

直接回答你的问题,你可以用 originalTextFor 来包裹你的值定义,这样就能得到一个字符串片段,里面包含了匹配的标记来源,结果是一个完整的字符串。你也可以加一个解析动作,比如:

value.setParseAction(lambda t : ' '.join(t))

不过这样做会在每个项目之间加一个空格,而实际上可能没有空格(比如在一个单词后面跟着逗号的情况),或者有多个空格。使用 originalTextFor 可以得到你输入的确切子字符串。但如果你只是想读取 ':' 后面的所有内容,使用 restOfLine 会更简单。(当然,最简单的方式是直接用 split(':'),但我猜你是特别想知道怎么用 pyparsing 来实现这个。)

还有几点补充:

  • xxx.setResultsName('yyy') 可以简化为 xxx('yyy'),这样能让你的解析器定义更易读。

  • 你定义的值为 OneOrMore(Word(unicode_printables) | Literal(',')) 有几个问题。首先,逗号 ',' 会被包含在 unicode_printables 的字符集中,所以解析出来的单词中也会包含逗号。解决这个问题的最好方法是使用 WordexcludeChars 参数,这样你的句子单词就不会包含逗号了:OneOrMore(Word(unicode_printables, excludeChars=',') | ',')。现在你也可以通过在 excludeChars 字符串中添加其他可能的标点符号(比如 ';'、'-' 等)来排除它们。(我刚注意到你用 '.' 作为 delimitedList 的分隔符——为了让这个工作,你也需要把 '.' 加入到排除的字符中。)在这方面,pyparsing 和普通的正则表达式不一样——它不会提前查看下一个标记是否匹配,如果下一个字符仍然匹配当前标记的话。因此,你需要自己做一些额外的工作,以避免读取过多。一般来说,像 OneOrMore(Word(unicode_printables)) 这样开放的定义,很可能会把你输入字符串的其余部分都吃掉。

撰写回答