Не жадный разбор с pyparsing - PullRequest
       29

Не жадный разбор с pyparsing

5 голосов
/ 12 августа 2011

Я пытаюсь разобрать строку с pyparsing.Эта строка состоит из ряда (ключ, значения).Я хотел бы получить список (ключ, значения).Простой пример:

ids = 12 fields = name

должен привести к чему-то вроде: [('ids', '12'), ('fields', 'name')]

Более сложный пример:

ids = 12, 13, 14 fields = name, title

должен привести к чему-то вроде: [('ids', '12, 13, 14'), ('fields', 'name, title')]

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

Но что бы я ни пытался до сих пор, я получаю такие результаты: [('ids', '12 fields')]

Пипарсинг съедает следующееключ, учитывая, что это также часть значения.

Вот пример кода:

import pyparsing as P

key = P.oneOf("ids fields")
equal = P.Literal('=')
key_equal = key + equal
val = ~key_equal + P.Word(P.alphanums+', ')

gr = P.Group(key_equal+val)
print gr.parseString("ids = 12 fields = name")

Может кто-нибудь помочь мне?Спасибо.

1 Ответ

7 голосов
/ 12 августа 2011

Первая проблема заключается в этой строке:

val = ~key_equal + P.Word(P.alphanums+', ')

Предполагается, что деталь соответствует любой буквенно-цифровой последовательности, за которой следует литерал ', ', но вместо этого она соответствует любой последовательности буквенно-цифровых символов ',' и ' '.

Вместо этого вы бы хотели:

val = ~key_equal + P.delimitedList(P.Word(P.alphanums), ", ", combine=True)

Вторая проблема заключается в том, что вы анализируете только одну пару ключ-значение:

gr = P.Group(key_equal+val)

Вместо этого вы должны разобрать как можно больше:

gr = P.Group(P.OneOrMore(key_equal+val))

Итак, правильное решение:

>>> import pyparsing as P
>>> key = P.oneOf("ids fields")
>>> equal = P.Literal('=')
>>> key_equal = key + equal
>>> val = ~key_equal + P.delimitedList(P.Word(P.alphanums), ", ", combine=True)
>>> gr = P.OneOrMore(P.Group(key_equal+val))
>>> print gr.parseString("ids = 12, 13, 14 fields = name, title")
[['ids', '=', '12, 13, 14'], ['fields', '=', 'name, title']]
...