gpt4 book ai didi

python - 简单地在 python 中使用 parsec

转载 作者:太空狗 更新时间:2023-10-29 22:08:40 25 4
gpt4 key购买 nike

我正在查看这个库,它几乎没有文档: https://pythonhosted.org/parsec/#examples

understand there are alternatives ,但我想使用这个库。

我有以下要解析的字符串:

mystr = """
<kv>
key1: "string"
key2: 1.00005
key3: [1,2,3]
</kv>
<csv>
date,windspeed,direction
20190805,22,NNW
20190805,23,NW
20190805,20,NE
</csv>"""

虽然我想解析整个事情,但我愿意只捕获 <tags> .我有:

>>> import parsec
>>> tag_start = parsec.Parser(lambda x: x == "<")
>>> tag_end = parsec.Parser(lambda x: x == ">")
>>> tag_name = parsec.Parser(parsec.Parser.compose(parsec.many1, parsec.letter))
>>> tag_open = parsec.Parser(parsec.Parser.joint(tag_start, tag_name, tag_end))

好的,看起来不错。现在开始使用它:

>>> tag_open.parse(mystr)
Traceback (most recent call last):
...
TypeError: <lambda>() takes 1 positional argument but 2 were given

这失败了。恐怕我什至不明白我的 lambda 表达式给出两个参数是什么意思,显然是 1。我该如何继续?

我对所有奖励积分的最佳期望输出是:

[
{"type": "tag",
"name" : "kv",
"values" : [
{"key1" : "string"},
{"key2" : 1.00005},
{"key3" : [1,2,3]}
]
},
{"type" : "tag",
"name" : "csv",
"values" : [
{"date" : 20190805, "windspeed" : 22, "direction": "NNW"}
{"date" : 20190805, "windspeed" : 23, "direction": "NW"}
{"date" : 20190805, "windspeed" : 20, "direction": "NE"}
]
}

在这个问题中我想要理解的输出是使用上面描述的函数来生成开始和结束标记:

[
{"tag": "kv"},
{"tag" : "csv"}
]

并且能够简单地从困惑的混合文本条目中解析出任意类似 xml 的标签。

最佳答案

我鼓励您使用这些组合器定义您自己的解析器,而不是直接构建Parser

如果你想通过包装一个函数来构造一个Parser,如文档所述,fn 应该接受两个参数,第一个是文本,第二个是当前位置。并且 fn 应该通过 Value.successValue.failure 返回一个 Value,而不是一个 bool 值。您可以在该包的 parsec/__init__.py 中使用 grep @Parser 来查找有关其工作原理的更多示例。

对于描述中的情况,您可以按如下方式定义解析器:

from parsec import *

spaces = regex(r'\s*', re.MULTILINE)
name = regex(r'[_a-zA-Z][_a-zA-Z0-9]*')

tag_start = spaces >> string('<') >> name << string('>') << spaces
tag_stop = spaces >> string('</') >> name << string('>') << spaces

@generate
def header_kv():
key = yield spaces >> name << spaces
yield string(':')
value = yield spaces >> regex('[^\n]+')
return {key: value}

@generate
def header():
tag_name = yield tag_start
values = yield sepBy(header_kv, string('\n'))
tag_name_end = yield tag_stop
assert tag_name == tag_name_end
return {
'type': 'tag',
'name': tag_name,
'values': values
}

@generate
def body():
tag_name = yield tag_start
values = yield sepBy(sepBy1(regex(r'[^\n<,]+'), string(',')), string('\n'))
tag_name_end = yield tag_stop
assert tag_name == tag_name_end
return {
'type': 'tag',
'name': tag_name,
'values': values
}

parser = header + body

如果你运行 parser.parse(mystr),它产生

({'type': 'tag',
'name': 'kv',
'values': [{'key1': '"string"'},
{'key2': '1.00005'},
{'key3': '[1,2,3]'}]},
{'type': 'tag',
'name': 'csv',
'values': [['date', 'windspeed', 'direction'],
['20190805', '22', 'NNW'],
['20190805', '23', 'NW'],
['20190805', '20', 'NE']]}
)

您可以优化上述代码中 values 的定义,以获得您想要的精确形式的结果。

关于python - 简单地在 python 中使用 parsec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57368870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com