«Депарсировать» список с помощью pyparsing - PullRequest
2 голосов
/ 06 июля 2010

Возможно ли дать pyparsing разобранный список и вернуть ли ему исходную строку?

1 Ответ

6 голосов
/ 08 июля 2010

Да, вы можете , если вы указали парсеру не выбрасывать какие-либо входные данные. Вы делаете это с помощью комбинатора Combine.

Допустим, ваш ввод:

>>> s = 'abc,def,  ghi'

Вот синтаксический анализатор, который захватывает точный текст списка:

>>> from pyparsing import *
>>> myList = Word(alphas) + ZeroOrMore(',' + Optional(White()) + Word(alphas))
>>> myList.leaveWhitespace()
>>> myList.parseString(s)
(['abc', ',', 'def', ',', '  ', 'ghi'], {})

Чтобы «разойтись»:

>>> reconstitutedList = Combine(myList)
>>> reconstitutedList.parseString(s)
(['abc,def,  ghi'], {})

, который возвращает вам начальный ввод.

Но это обходится ценой: все лишние пробелы, плавающие в виде токенов, обычно не удобны, и вы заметите, что нам пришлось явно отключить пропуск пробелов в в myList. Вот версия, которая удаляет пробелы:

>>> myList = Word(alphas) + ZeroOrMore(',' + Word(alphas))
>>> myList.parseString(s)
(['abc', ',', 'def', ',', 'ghi'], {})
>>> reconstitutedList = Combine(myList, adjacent=False)
>>> reconstitutedList.parseString(s)
(['abc,def,ghi'], {})

Обратите внимание, что в данный момент вы не получаете буквальный ввод, но этого может быть достаточно для вас. Также обратите внимание, что мы должны были явно указать Combine, чтобы пропустить пропуски.

Правда, во многих случаях вы даже не заботитесь о разделителях; Вы хотите, чтобы анализатор сосредоточился на самих элементах. Есть функция под названием commaSeparatedList, которая удобно удаляет разделители и пробелы для вас:

>>> myList = commaSeparatedList
>>> myList.parseString(s)
(['abc', 'def', 'ghi'], {})

В этом случае, однако, на шаге «отстранения» недостаточно информации для восстановленной строки, чтобы иметь смысл:

>>> reconstitutedList = Combine(myList, adjacent=False)
>>> reconstitutedList.parseString(s)
(['abcdefghi'], {})
...