无法正确解析这个文件使用pyparsing。

2024-05-16 23:03:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用神奇的python库pyparsing解析一个文件,但是我遇到了很多问题。。。在

我试图解析的文件类似于:

sectionOne:
  list:
  - XXitem
  - XXanotherItem
  key1: value1
  product: milk
  release: now
  subSection:
    skey : sval
    slist:
    - XXitem
  mods:
  - XXone
  - XXtwo
  version: last
sectionTwo:
  base: base-0.1
  config: config-7.0-7

如您所见,是一个缩进的配置文件,这或多或少就是我试图定义语法的方式

  • 文件可以有一个或多个节
  • 每个节由节名称和节内容组成。在
  • 每个部分都有缩进的内容
  • 每个节内容可以有一对或多对键/值或子节。在
  • 每个值可以只是一个单词或一个项目列表。在
  • 项目列表是由一个或多个项目组成的一组。在
  • 每个项目都是连字符+以“XX”开头的名称

我尝试使用pyparsing创建这个语法,但是没有成功。在

^{pr2}$

结果是:

result1:
  [['sectionOne', [[['list', ['XXitem', 'XXanotherItem']], ['key1', 'value1'], ['product', 'milk'], ['release', 'now'], ['subSection', [[['skey', 'sval'], ['slist', ['XXitem']], ['mods', ['XXone', 'XXtwo']], ['version', 'last']]]]]]], ['sectionTwo', [[['base', 'base-0.1'], ['config', 'config-7.0-7']]]]]
  len 2
  [
     ['sectionOne',
     [[
        ['list', ['XXitem', 'XXanotherItem']],
        ['key1', 'value1'],
        ['product', 'milk'],
        ['release', 'now'],
        ['subSection',
           [[
              ['skey', 'sval'],
              ['slist', ['XXitem']],
              ['mods', ['XXone', 'XXtwo']],
              ['version', 'last']
           ]]
        ]
     ]]
     ],
     ['sectionTwo', 
     [[
        ['base', 'base-0.1'], 
        ['config', 'config-7.0-7']
     ]]
     ]
  ]

如你所见,我有两个主要问题:

1.-每个节内容嵌套到一个列表中两次

2.-键“version”在属于“sectionOne”时在“subSection”内解析

我的真正的目标是能够获得一个包含键和值的python嵌套字典的结构,以便轻松地提取每个字段的信息,但是pyparsing.Dict对我来说很模糊。在

谁能帮帮我吗?在

提前谢谢

(抱歉发了这么长的帖子)


Tags: 文件项目config内容baseversionpyparsingproduct
1条回答
网友
1楼 · 发布于 2024-05-16 23:03:10

你真的很接近——恭喜你,缩进的解析器并不是最容易用pyparsing编写的。在

请看注释的更改。标记为“A”的更改是为了修复您所声明的两个问题。那些用“B”标记的添加Dict构造,这样您就可以使用config中的名称将解析的数据作为嵌套结构访问。在

最大的罪魁祸首是indentedBlock为您做了一些额外的分组,这妨碍了Dict的名称-值关联。使用ungroup将其剥离,可以让Dict看到底层对。在

祝pyparsing好运!在

import pprint
import pyparsing
NEWLINE = pyparsing.LineEnd().suppress()
VALID_CHARACTERS = pyparsing.srange("[a-zA-Z0-9_\-\.]")
COLON = pyparsing.Suppress(pyparsing.Literal(":"))
HYPHEN = pyparsing.Suppress(pyparsing.Literal("-"))
XX = pyparsing.Literal("XX")

list_item = HYPHEN + pyparsing.Combine(XX + pyparsing.Word(VALID_CHARACTERS))
list_of_items = pyparsing.Group(pyparsing.OneOrMore(list_item))

key = pyparsing.Word(VALID_CHARACTERS) + COLON
pair_value = pyparsing.Word(VALID_CHARACTERS) + NEWLINE
value = (pair_value | list_of_items)

#~ A: pair = pyparsing.Group(key + value)
pair = (key + value)

indentStack = [1]

section = pyparsing.Forward()
section_name = pyparsing.Word(VALID_CHARACTERS) + COLON
#~ A: section_value = pyparsing.OneOrMore(pair | section)
section_value = (pair | section)

#~ B: section_content = pyparsing.indentedBlock(section_value, indentStack, True)
section_content = pyparsing.Dict(pyparsing.ungroup(pyparsing.indentedBlock(section_value, indentStack, True)))

#~ A: section << Group(section_name + section_content)
section << (section_name + section_content)

#~ B: parser = pyparsing.OneOrMore(section)
parser = pyparsing.Dict(pyparsing.OneOrMore(pyparsing.Group(section)))

现在,您可以编写以下内容,而不是pprint(result.asList())

^{pr2}$

要显示Dict层次结构:

^{3}$

允许您编写如下语句:

print (result.sectionTwo.base)

相关问题 更多 >