pyparsing SkipTo 和 key = value 输入
pyparsing SkipTo and key = value input
我正在尝试使用 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"数据输入:
$raw
H 0.0 0.0 0.0
F 1.0 1.0 1.0
$end
其中 $
和 $end
之间的任何内容都是 "gobbled up" 的字符串,其键为 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
和 "raw" 数据解析器的方式:
parser = pp.dictOf(_key, _value) ^ data_t
解析后调用为:
tokens = parser.parseString(keywords).asDict()
这个return一个空的dict
。将 int = 42
移动到 $raw ... $end
上方 return 只是 {'int': 42 }
.
哟哟!这部分是由于 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 中添加名称,请将定义更改为此,并删除解析操作:
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
我正在尝试使用 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"数据输入:
$raw
H 0.0 0.0 0.0
F 1.0 1.0 1.0
$end
其中 $
和 $end
之间的任何内容都是 "gobbled up" 的字符串,其键为 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
和 "raw" 数据解析器的方式:
parser = pp.dictOf(_key, _value) ^ data_t
解析后调用为:
tokens = parser.parseString(keywords).asDict()
这个return一个空的dict
。将 int = 42
移动到 $raw ... $end
上方 return 只是 {'int': 42 }
.
哟哟!这部分是由于 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 中添加名称,请将定义更改为此,并删除解析操作:
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