PyParsing нежадное совпадение

Я пытаюсь разобрать частично стандартизированный почтовый адрес на его компоненты, используя pyparsing. Я хочу нежадно сопоставить название улицы, длина которого может составлять N токенов.

Например:

444 PARK GARDEN LN

Следует разобрать на:

number: 444
street: PARK GARDEN
suffix: LN

Как бы я сделал это с PyParsing? Вот мой исходный код:

from pyparsing import *

def main():
    street_number = Word(nums).setResultsName('street_number')
    street_suffix = oneOf("ST RD DR LN AVE WAY").setResultsName('street_suffix')
    street_name = OneOrMore(Word(alphas)).setResultsName('street_name')

    address = street_number + street_name + street_suffix
    result = address.parseString("444 PARK GARDEN LN")
    print result.dump()

if __name__ == '__main__':
    main()

но когда я пытаюсь разобрать его, суффикс улицы поглощается жадным поведением синтаксического анализа по умолчанию.


person zzz    schedule 10.04.2013    source источник


Ответы (1)


Используйте отрицание ~, чтобы проверить, действительно ли предстоящее street_name является street_suffix.

from pyparsing import *

street_number = Word(nums)('street_number')
street_suffix = oneOf("ST RD DR LN AVE WAY")('street_suffix')
street_name = OneOrMore(~street_suffix + Word(alphas))('street_name')

address = street_number + street_name + street_suffix
result = address.parseString("444 PARK GARDEN LN")
print result.dump()

Кроме того, вам не обязательно использовать setResultsName, вы можете просто использовать приведенный выше синтаксис. ИМХО, это приводит к более четкому определению грамматики.

person Hooked    schedule 11.04.2013
comment
Очень хороший ответ, хотел бы я дать второй голос за подсказку об альтернативной форме для setResultsName. К ОП: анализ адресов улиц чрезвычайно сложен, на вики-странице pyparsing есть образец (pyparsing.wikispaces.com/file/view/streetAddressParser.py/), что может дать вам более быстрый старт. - person PaulMcG; 30.04.2013