Ну, я мог бы немного упростить мои комментарии - вот более полный ответ .
Если вы действительно не должны иметь дело с вложенными элементами данных, то одноуровневые скобками группы данных в каждой секции будет выглядеть следующим образом:
LPAR,RPAR = map(Suppress, "()")
ident = Word(alphas, alphanums + "-_")
integer = Word(nums)
# treat consecutive quoted strings as one combined string
quoted_string = OneOrMore(quotedString)
# add parse action to concatenate multiple adjacent quoted strings
quoted_string.setParseAction(lambda t: '"' +
''.join(map(lambda s:s.strip('"\''),t)) +
'"' if len(t)>1 else t[0])
data_item = ident | integer | quoted_string
# section defined with no nesting
section = ident + Group(LPAR + delimitedList(data_item) + RPAR)
Я не был уверен, что если бы это было преднамеренно или нет, когда вы пропустили запятую между двумя последовательными цитированными строками, поэтому я решил реализовать логику, такую как компилятор Python, , в котором две цитируемые строки рассматриваются как одна длинная строка, то есть "AB CD " "EF"
- это то же, что и "AB CD EF"
. Это было сделано с определением quoted_string и добавлением действия синтаксического анализа к quoted_string для конкатенации содержимого двух или более компонентов цитируемых строк.
Наконец, мы создаем парсер для общей группы
results = OneOrMore(Group(section)).parseString(source)
results.pprint()
и получить от вашего публикуемую ввода образца:
[['acp',
['SOLO1',
'"solo-100"',
'"hi here is the giftMaximum amount of money, goes"',
'430',
'90']],
['jhk',
['SOLO2',
'"solo-101"',
'"hi here goes the wind.and, they go beyond"',
'1000',
'320']]]
Если вы сделать гнездились вводные группы, то ваше определение раздела может быть так просто:
# section defined with nesting
section = ident + nestedExpr()
Хотя, как вы уже нашли, это сохранит отдельные запятые, как если бы они были важными токенами, а не только разделителями данных.
Нет необходимости определять nestedExpr с помощью Forward-nestedExpr, который позаботится обо всех вложенных вложениях. Для этого вам просто нужно 'section = flag + nestedExpr (content = Word (nums) | flag | quotedString)', а затем проанализировать для 'OneOrMore (section)'. – PaulMcG