gpt4 book ai didi

python - PyParsing 表示函数的字符串

转载 作者:行者123 更新时间:2023-12-01 05:32:29 25 4
gpt4 key购买 nike

我有一个如下所示的数据:

data = 'person(firstame="bob", lastname="stewart", dob="2010-0206", hobbies=["reading, singing", "drawing"], is_minor=True)'

我编写的语法解析规则如下:

quotedString.setParseAction(removeQuotes)
list_of_names = delimitedList(quotedString)

person_start = Literal("person(").suppress()
first = Literal("firstname") + Suppress("=") + quotedString
lastname = Literal("lastname") + Suppress("=") + quotedString
dob = Literal("dob") + Suppress("=") + quotedString
hobbies = Literal("hobbies") + Suppress("=[") + list_of_names + Suppress("]")
is_minor = Literal("is_minor") + Suppress("=") + oneOf("True False")
person_end = Suppress(")")
comma = Literal(",").suppress()

my_data = person_start + first + comma + last + comma + dob +comma + hobbies + comma + is_minor + person_end
result = my_data.parseString(data)

我的问题是 3:

  1. 上述规则有效,但我想确定是否有更好的方法来编写它。
  2. 在我的数据中,无法保证顺序,因此姓氏可以出现在名字之前,我如何确保这一点。
  3. 最终在解析之后我想把所有内容都作为字典,所以 key:value第一:“鲍勃”爱好:[“阅读”、“唱歌”、“绘画”]......最好的方法是什么。

最佳答案

您发布的代码中有一些小拼写错误(数据中的firstame="bob"firstname="bob"lastname > 与last),但是清理它们之后,看起来还不错。如果打印结果,您将得到:

['firstname', 'bob', 'lastname', 'stewart', 'dob', '2010-0206', 
'hobbies', 'reading, singing', 'drawing', 'is_minor', 'True']

首先,我建议,正如您将 list_of_names (来自您之前的问题 pyparsing string of quoted names )定义为可能的值类型一样,您定义一个 bool 值来解析 True/False 值。使用 oneOf 很好,让我们添加一个解析操作,将字符串“True”和“False”转换为实际的 Python bool 值:

boolean_value = oneOf("True False").setParseAction(lambda t: t[0]=='True')

这类似于在 QuotedString 上使用 removeQuotes

现在,解析结果如下所示:

['firstname', 'bob', 'lastname', 'stewart', 'dob', '2010-0206', 
'hobbies', 'reading, singing', 'drawing', 'is_minor', True]

请注意,True 现在不是字符串,而是 Python 值 True(该值周围没有引号)。

现在回答你问题的第一部分,如何将其变成字典。 Pyparsing 允许您为语法的不同部分定义结果名称,以便在解析数据后,您可以通过名称访问这些值。执行此操作的语法过去是调用方法 setResultsName:

my_data = person_start + first.setResultsName("firstname") + 
last.setResultsName("lastname") + ...

我发现这有点麻烦,并且使用所有“.setResultsName”方法调用该表达式更难阅读。不久前,我更改了 API 以接受以下语法:

my_data = person_start + first("firstname") + last("lastname") + ...

但是您定义的 firstlast 等不仅仅包含值,还包含标签。

简化语法的一种方法是创建一个自己的小辅助方法,我们将其称为named_pa​​rameter:

def named_parameter(label, paramtype):
expr = Literal(label) + Suppress('=') + paramtype(label)
return expr

请注意,label 用于指定文字字符串值的结果名称。现在您可以将语法定义为:

first = named_parameter("firstname", quotedString)
last = named_parameter("lastname", quotedString)
dob = named_parameter("dob", quotedString)
hobbies = named_parameter("hobbies", Suppress("[") + list_of_names + Suppress("]"))
is_minor = named_parameter("is_minor", boolean_value)

使用命名的值,您可以将解析结果作为 Python 字典访问:

print result["firstname"]
print result["hobbies"]

打印:

bob
['reading, singing', 'drawing']

或者,如果您愿意,也可以使用对象属性表示法:

print result.firstname
print result.hobbies

为了回答问题的第二部分,您询问了如何处理参数可能乱序的情况。最简单的方法是再次使用 delimitedList:

parameter = first | last | dob | hobbies | is_minor
my_data = person_start + delimitedList(parameter) + person_end

这不是一个严格的解析器,它会接受不包含所有参数的参数列表,或者包含重复参数的列表。但对于现有的有效代码,它将解析带有任意顺序参数的列表。

这是最终的解析器:

quotedString.setParseAction(removeQuotes)
list_of_names = delimitedList(quotedString)
boolean_value = oneOf("True False").setParseAction(lambda t: t[0]=='True')

def named_parameter(label, paramtype):
expr = Literal(label) + Suppress('=') + paramtype(label)
return expr

person_start = Literal("person(").suppress()
first = named_parameter("firstname", quotedString)
last = named_parameter("lastname", quotedString)
dob = named_parameter("dob", quotedString)
hobbies = named_parameter("hobbies", Suppress("[") + list_of_names + Suppress("]"))
is_minor = named_parameter("is_minor", boolean_value)
person_end = Suppress(")")
comma = Literal(",").suppress()

parameter = first | last | dob | hobbies | is_minor
my_data = person_start + delimitedList(parameter) + person_end

关于python - PyParsing 表示函数的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19885047/

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