Получить целое предложение в юникоде - PullRequest
2 голосов
/ 06 октября 2011

Я пытаюсь разобрать предложение, как 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)

И вроде работает, но это сбрасывает символы в кодировке Юникод (и что бы то ни было в алфавитах), и я думаю, что я хотел бы иметь value как целое предложение, а не так: 'value': [(([u'Lote', u'Numero', u'1', ',', u'Marcelo', u'T', u'de', u'Alvear', u'500'], {}), 1).

Это простой способ решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 06 октября 2011

Чтобы напрямую ответить на ваш вопрос, оберните определение значения с помощью originalTextFor, и это вернет вам фрагмент строки, из которого получены соответствующие токены, как одну строку. Вы также можете добавить действие разбора, например:

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

Но это явно поставило бы один пробел между каждым элементом, когда, возможно, не было пробелов (в случае ',' после слова) или более одного пробела. originalTextFor даст вам точную входную подстроку. Но еще проще, если вы просто читаете все после ':', было бы использовать restOfLine. (Конечно, самым простым было бы просто использовать split(':'), но я предполагаю, что вы конкретно спрашиваете, как это сделать с помощью pyparsing.)

Пара других заметок:

  • xxx.setResultsName('yyy') можно сократить до xxx('yyy'), что улучшит читабельность определения вашего синтаксического анализатора.

  • Ваше определение значения как OneOrMore(Word(unicode_printables) | Literal(',')) имеет несколько проблем. С одной стороны, ',' будет включено в набор символов в unicode_printables, поэтому ',' будет включено в любые проанализированные слова. Лучший способ решить эту проблему - использовать параметр excludeChars для Word, чтобы слова предложения не содержали запятых: OneOrMore(Word(unicode_printables, excludeChars=',') | ','). Теперь вы также можете исключить другие возможные знаки препинания, такие как ';', '-' и т. Д., Просто добавив их в строку excludeChars. (Я только что заметил, что вы используете «.» В качестве разделителя для delimitedList - чтобы это работало, вы должны будете также включить «.» В качестве исключенного символа.) В этом отношении Pyparsing не похож на регулярное выражение - он не делает никаких попыток поиска совпадения со следующим токеном в анализаторе, если следующий символ продолжает совпадать с текущим токеном. Вот почему вы должны выполнить некоторую дополнительную работу, чтобы не читать слишком много. В общем, что-то такое открытое, как OneOrMore(Word(unicode_printables)), очень вероятно съест всю оставшуюся часть вашей входной строки.

1 голос
/ 06 октября 2011

Вам следует заглянуть в PyICU , который предоставляет доступ к расширенной текстовой библиотеке Unicode, предоставляемой ICU, включая класс BreakIterator , который предоставляет искатель предложений.

...