2

我正在尝试像Base: Lote Numero 1, Marcelo T de Alvear 500. Demanda: otras palabras.我想要的那样解析一个句子:首先,用句点分割文本,然后,使用冒号之前的任何内容作为冒号label之后的句子。现在我有以下定义:

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)

和一种作品,但它放弃了 unicode 字符(以及任何不在字母数字中的字符),我想我希望有value一个完整的句子而不是这个:'value': [(([u'Lote', u'Numero', u'1', ',', u'Marcelo', u'T', u'de', u'Alvear', u'500'], {}), 1)

有一个简单的方法来解决这个问题吗?

4

2 回答 2

2

要直接回答您的问题,请使用 包装您的值定义originalTextFor,这会将匹配标记来自的字符串切片作为单个字符串返回给您。您还可以添加解析操作,例如:

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

但这会在每个项目之间显式地放置一个空格,当可能没有空格(在一个单词之后的“,”的情况下)或多个空格时。 originalTextFor将为您提供确切的输入子字符串。但更简单的是,如果您只是阅读 ':' 之后的所有内容,则可以使用restOfLine. (当然,最简单的就是使用split(':'),但我假设您是专门询问如何使用 pyparsing 来做到这一点。)

其他几点注意事项:

  • xxx.setResultsName('yyy')可以缩短为 just xxx('yyy'),提高解析器定义的可读性。

  • 您对价值的定义OneOrMore(Word(unicode_printables) | Literal(','))存在几个问题。一方面,',' 将包含在 中的字符集中unicode_printables,因此 ',' 将包含在任何已解析的单词中。解决这个问题的最好方法是使用excludeChars参数 to Word,让你的句子单词不包含逗号:OneOrMore(Word(unicode_printables, excludeChars=',') | ','). 现在您还可以排除其他可能的标点符号,例如 ';'、'-' 等,只需将它们添加到 excludeChars 字符串中即可。(我刚刚注意到您使用 '.' 作为分隔符delimitedList- 为此,您必须包含“。” 作为一个排除字符。)在这方面,Pyparsing 不像正则表达式 - 如果下一个字符继续匹配当前标记,它不会做任何前瞻来尝试匹配解析器中的下一个标记。这就是为什么你必须自己做一些额外的工作以避免阅读太多。一般来说,一些开放式的东西OneOrMore(Word(unicode_printables))很可能会吃掉你输入字符串的其余部分。

于 2011-10-06T10:34:20.187 回答
1

您应该查看PyICU,它提供对 ICU 提供的富 Unicode 文本库的访问,包括提供句子查找器的BreakIterator类。

于 2011-10-06T02:17:42.523 回答