繁体   English   中英

PyParsing Parse 嵌套循环,带大括号和特定标头

[英]PyParsing Parse nested loop with brace and specific header

我发现了几个关于 pyparsing 的主题。 他们在解析嵌套循环时处理几乎相同的问题,但即使如此,我也找不到解决我的错误的方法。

我有以下格式:

key value;
header_name "optional_metadata"
{
     key value;
     sub_header_name
     {
        key value;
     };
};
key value;
  • 键是字母
  • 值可以是 Int、String 类型,带有字母 + "@._"
  • 键/值可能在大括号块之后
  • 键/值可能在第一个大括号块之前的文件中
  • 大括号块之前或之后的键/值是可选的
  • 标题可能有一个名字
  • 右大括号后跟一个分号

我使用了以下解析器:

VALID_KEY_CHARACTERS = alphanums
VALID_VALUE_CHARACTERS = srange("[a-zA-Z0-9_\"\'\-\.@]")

lbr = Literal( '{' ).suppress()
rbr = Literal( '}' ).suppress() + Literal(";").suppress()

expr = Forward()
atom = Word(VALID_KEY_CHARACTERS) + Optional(Word(VALID_VALUE_CHARACTERS))
pair = atom | lbr + OneOrMore( expr ) + rbr
expr << Group( atom + pair )

当我使用它时,我只得到了“header_name”和“header_metadata”,我修改了它,并且我只得到了括号内的键/值,python 异常被触发以显示解析错误(它期望在到达子标题名称。

任何人都可以帮助我理解为什么? 谢谢你。

我认为主要的问题是您的语法无法完全描述输入,从而导致一些不匹配。 我看到的两个主要问题是,您忘记了每个键对值都必须以分号结尾,并且没有指定键对值可以在大括号后出现。 它也看起来像这样:

pair = atom | lbr + OneOrMore( expr ) + rbr
expr << Group( atom + pair )

...将要求每组花括号至少包含两个键对值或一个键对值和一组花括号。 我相信一旦您遇到以下问题,这将导致错误:

{
    key value;
};

...在您的意见范围内,尽管我不确定。

无论如何,在玩完您的语法后,我得出了以下结论:

from pyparsing import *

data = """key1 value1; 
header_name "optional_metadata"
{
     key2 value2;
     sub_header_name
     {
        key value;
     };
};
key3 value3;"""

# I'm reusing the key characters for the header names, which can contain a semicolon
VALID_KEY_CHARACTERS = srange("[a-zA-Z0-9_]")
VALID_VALUE_CHARACTERS = srange("[a-zA-Z0-9_\"\'\-\.@]")

semicolon = Literal(';').suppress()
lbr = Literal('{').suppress()
rbr = Literal('}').suppress()

key = Word(VALID_KEY_CHARACTERS)
value = Word(VALID_VALUE_CHARACTERS)

key_pair = Group(key + value + semicolon)("key_pair")
metadata = Group(key + Optional(value))("metadata")

header = key_pair + Optional(metadata)

expr = Forward()
contents = Group(lbr + expr + rbr + semicolon)("contents")
expr << header + Optional(contents) + Optional(key_pair)

print expr.parseString(data).asXML()

结果为以下输出:

<key_pair>
  <key_pair>
    <ITEM>key1</ITEM>
    <ITEM>value1</ITEM>
  </key_pair>
  <metadata>
    <ITEM>header_name</ITEM>
    <ITEM>&quot;optional_metadata&quot;</ITEM>
  </metadata>
  <contents>
    <key_pair>
      <ITEM>key2</ITEM>
      <ITEM>value2</ITEM>
    </key_pair>
    <metadata>
      <ITEM>sub_header_name</ITEM>
    </metadata>
    <contents>
      <key_pair>
        <ITEM>key</ITEM>
        <ITEM>value</ITEM>
      </key_pair>
    </contents>
  </contents>
  <key_pair>
    <ITEM>key3</ITEM>
    <ITEM>value3</ITEM>
  </key_pair>
</key_pair>

我不确定这是否正是您要完成的任务,希望它应该足够接近以便您可以调整它以适合您的特定任务。

我试图使用 python 解析 terraform 资源并遇到与您相同的问题。

这是我的解析器的要点

测试用例文件“repository.tf”是您可以看到解析器如何解析具有特定标题的嵌套大括号的文件

https://gist.github.com/antigenius0910/5e00e80cfadf48642acb44132acefb3a#file-parse-py-L95-L101

~/Downloads/5e00e80cfadf48642acb44132acefb3a-b514369c817885589911ca2c81fa367af4851d86 ᐅ python parse.py 

resource "github_repository" "tfer--test-002D-plugin-002D-example" {
  allow_merge_commit     = "true"
  allow_rebase_merge     = "true"
  allow_squash_merge     = "true"
  archived               = "true"
  default_branch         = "main"
  delete_branch_on_merge = "false"
  has_downloads          = "true"
  has_issues             = "true"
  has_projects           = "false"
  has_wiki               = "true"
  is_template            = "false"
  name                   = "test-plugin-example"
  private                = "true"

  template {
    owner      = "test"
    repository = "test-plugin-templattest-plugin-template"
  }

  visibility           = "internal"
  vulnerability_alerts = "false"
}

希望这会有所帮助:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM