pyparsing SkipTo和键=值输入

时间:2018-12-15 20:51:07

标签: python-3.x pyparsing

我正在尝试使用pyparsing定义输入解析器。我设法正确解析了以下内容:

key = value

其中值可以是例如整数。这是Python代码:

import pyparsing as pp

_name = pp.Word(pp.alphas + '_', pp.alphanums + '_')
_key = _name + EQ
_value = pp.pyparsing_common.signed_integer

pp.dictOf(_key, _value)

现在,我想添加一个“原始”数据输入:

$raw
H 0.0 0.0 0.0
F 1.0 1.0 1.0
$end

其中$$end之间的任何内容都被“拼凑”成一个字符串,其关键字将为raw。我尝试过:

import pyparsing as pp

SDATA = pp.Literal('$').suppress()
EDATA = pp.CaselessLiteral('$end').suppress()
data_t = pp.Combine(SDATA + pp.Word(pp.alphas + '_', pp.alphanums + '_')
                ) + pp.SkipTo(EDATA) + EDATA
data_t.setName('raw data')
data_t.setParseAction(lambda token: (token[0], token[1]))

,这适用于输入字符串'$raw\nH 0.0 0.0 0.0\nF 1.0 1.0 1.0\n$end' 但是,我无法将key = value解析器与data_t组合在一起。有什么明显的我想念的地方吗?还是不可能将两者结合起来?

更新

这是测试输入:

$raw
H 0.0 0.0 0.0
F 1.0 1.0 1.0
$end

int = 42

这是我将key = value和“原始”数据解析器组合在一起的方式:

parser = pp.dictOf(_key, _value) ^ data_t

带有解析,然后调用为:

tokens = parser.parseString(keywords).asDict()

这将返回一个空的dict。将int = 42移到$raw ... $end上方只会返回{'int': 42 }

1 个答案:

答案 0 :(得分:1)

Y!部分原因是dictOf中的错误。为了在此方面取得进展,我定义了以下内容:

kv_dict = pp.Dict(pp.OneOrMore(pp.Group(_key + _value)))

然后我将解析器定义为:

parser = pp.OneOrMore(pp.Group(data_t) | pp.Group(kv_dict))

分组很重要,因此一组中的键不会踩到另一组中的键。 (dictOf中的错误阻止了将其像这样包含在OneOrMore中,因为dictOf允许一个空的字典,因此它会在字符串的末尾永远循环而不是终止。)

最后,我使用dump()而不是asDict()来查看结果。 asDict()仅显示已命名的已解析令牌,而您的data_t未显示。

print(parser.parseString(sample).dump())

礼物:

[[('raw', 'H 0.0 0.0 0.0\nF 1.0 1.0 1.0\n')], [['int', 42]]]
[0]:
  [('raw', 'H 0.0 0.0 0.0\nF 1.0 1.0 1.0\n')]
[1]:
  [['int', 42]]
  - int: 42

如果要在data_t中添加名称,请将其定义更改为该名称,然后删除parse操作:

data_t = pp.Combine(SDATA + pp.Word(pp.alphas + '_', pp.alphanums + '_')
                )("name") + pp.SkipTo(EDATA)("body") + EDATA

现在我得到了:

[['raw', 'H 0.0 0.0 0.0\nF 1.0 1.0 1.0\n'], [['int', 42]]]
[0]:
  ['raw', 'H 0.0 0.0 0.0\nF 1.0 1.0 1.0\n']
  - body: 'H 0.0 0.0 0.0\nF 1.0 1.0 1.0\n'
  - name: 'raw'
[1]:
  [['int', 42]]
  - int: 42