我必须解析具有嵌套结构的文档。
它包含具有标题以及成对的键和值的部分。
txt_1 = '''
header1:
key1: 1a
key2: 2b
'''
txt_2 = '''
section1:
key1: 1a
section2:
key2: 2b
key3: 3c
'''
我在pyparsing
中编写了简单的语法,该语法对于仅包含一个部分的简单文档可以很好地工作,但是当我尝试用空行分隔具有多个部分的文档时,语法将失败。
HEADER = (
(
Word(alphanums)
+ Suppress(Literal(':'))
).setResultsName('header')
)
PARAM = Word(alphanums).setResultsName('param')
VALUE = Word(alphanums).setResultsName('value')
LINE = (
Group(
PARAM
+ Suppress(Literal(':'))
+ VALUE
)
)
LINES = (
OneOrMore(
LINE
)
).setResultsName('body')
SECTION = (
Group(
HEADER
+ LINES
)
.setResultsName('section')
)
GRAMMAR = OneOrMore(SECTION).setResultsName('section')
GRAMMAR.parseString(txt).asList()
对于txt_1
来说,它可以正常工作,但是对于txt_2
,它的两个部分用空行分开,则将第2部分的部分视为第1部分。
[['section1', ['key1', '1a'], ['section2', 'key2']]]
我尝试了以下标记使用不同的方法,但没有成功。
N = White('\n', exact=1)
EMPTY = LineStart()+LineEnd()
答案 0 :(得分:1)
下面的代码充分利用了对新节以“ 字母数字:字母数字: ”模式开头的观察。负向超前~
( NotAny )用于阻止body
解析器吞噬下一部分标头。
为line
结果名称(后缀*
)设置了 setResultsName 参数 listAllMatches ,以便词典可以列出多个匹配项。 / p>
pyparsing 默认情况下会跳过空格,除非在某些情况下(例如使用 Combine 时),所以这里无需考虑。
from pyparsing import *
COLON = Suppress(':')
param = Word(alphanums)("param")
value = Word(alphanums)("value")
line = Group(param + COLON + value)
new_section_check = (Word(alphanums) + COLON) * 2
body = OneOrMore(~new_section_check + line("line*"))
section = Group(Word(alphanums)("section") + COLON + body)
contents = OneOrMore(section)
text = """
section1:
key1: 1a
section2:
key2: 2b
key3: 3c
"""
print(contents.parseString(text).dump())
产生以下内容:
[['section1', ['key1', '1a']], ['section2', ['key2', '2b'], ['key3', '3c']]]
[0]:
['section1', ['key1', '1a']]
- line: [['key1', '1a']]
[0]:
['key1', '1a']
- param: 'key1'
- value: '1a'
- section: 'section1'
[1]:
['section2', ['key2', '2b'], ['key3', '3c']]
- line: [['key2', '2b'], ['key3', '3c']]
[0]:
['key2', '2b']
- param: 'key2'
- value: '2b'
[1]:
['key3', '3c']
- param: 'key3'
- value: '3c'
- section: 'section2'