Python pyparsing:将多个元素的setResultsName合并

Python pyparsing:将多个元素的setResultsName合并,python,pyparsing,Python,Pyparsing,以下是我正在分析的文本: x ~ normal(mu, 1) y ~ normal(mu2, 1) 解析器使用以下方法匹配这些行: model_definition = Group(identifier.setResultsName('random_variable_name') + '~' + expression).setResultsName('model_definition') // end of line: .setResultsName('model_definition')

以下是我正在分析的文本:

x ~ normal(mu, 1)
y ~ normal(mu2, 1)
解析器使用以下方法匹配这些行:

model_definition = Group(identifier.setResultsName('random_variable_name') + '~' + expression).setResultsName('model_definition')

// end of line: .setResultsName('model_definition')
问题在于,当存在两个模型定义时,它们在ParseResults对象中不会单独命名:

看起来第一个被第二个覆盖了。我命名它们的原因是为了使执行这些行更容易——这样我(希望)不必在计算时弄清楚发生了什么——解析器已经标记了所有内容。如何将
model\u定义
s两者都贴上标签?如果
model\u definition
包含找到的每个模型定义的列表,那就太好了

以防万一,下面是我的一些代码:

model_definition = Group(identifier.setResultsName('random_variable_name') + '~' + expression).setResultsName('model_definition')
expression << Or([function_application, number, identifier, list_literal, probability_expression])
statement = Optional(newline) + Or([model_definition, assignment, function_application]) + Optional(newline)
line = OneOrMore('\n').suppress()
comment = Group('#' + SkipTo(newline)).suppress()
program = OneOrMore(Or([line, statement, comment]))
ast = program.parseString(input_string)
return ast
model_definition=Group(identifier.setResultsName('random_variable_name')+'~'+表达式)。setResultsName('model_definition'))

表达式据我所知没有文档记录,但我在
pyparsing.py
中发现了一些东西:

我将
.setResultsName('model_definition')
更改为
.setResultsName('model_definition*')
,它们正确列出了

编辑:有文档记录,但它是传递给
setResultsName
的标志:

setResultsName(string,listAllMatches=False)-为与元素匹配的令牌指定的名称;如果重复组中有多个标记(如ZeroOrMore或delimitedList),则默认情况下仅返回最后一个匹配标记-如果listAllMatches设置为True,则返回匹配标记的列表


以下是足够的代码,可以让您的工作正常进行:

from pyparsing import *

# fake in the bare minimum to parse the given test strings
identifier = Word(alphas, alphanums)
integer = Word(nums)
function_call = identifier + '(' + Optional(delimitedList(identifier | integer)) + ')'
expression = function_call

model_definition = Group(identifier.setResultsName('random_variable_name') + '~' + expression)

sample = """
x ~ normal(mu, 1)
y ~ normal(mu2, 1)
"""
对于使用缩写形式的
setResultsName
expr(“name*”)
vs
expr.setResultsName(“name”,listAllMatches=True)的情况,在
setResultsName
中有尾随的
“*”
。如果您喜欢调用
setResultsName
,那么我不会使用
'*'
符号,而是会传递
listAllMatches
参数

如果您得到的名称相互重叠,则可能需要添加一个级别的分组。以下是您的解决方案,使用
listAllMatches=True
,借助尾随的
'*'
符号:

model_definition1 = model_definition('model_definition*')
print OneOrMore(model_definition1).parseString(sample).dump()
它返回以下解析结果:

[['x', '~', 'normal', '(', 'mu', '1', ')'], ['y', '~', 'normal', '(', 'mu2', '1', ')']]
- model_definition: [['x', '~', 'normal', '(', 'mu', '1', ')'], ['y', '~', 'normal', '(', 'mu2', '1', ')']]
  [0]:
    ['x', '~', 'normal', '(', 'mu', '1', ')']
    - random_variable_name: x
  [1]:
    ['y', '~', 'normal', '(', 'mu2', '1', ')']
以下是一个变体,它不使用
listalmatches
,而是添加了另一个级别的组:

model_definition2 = model_definition('model_definition')
print OneOrMore(Group(model_definition2)).parseString(sample).dump()
给出:

[[['x', '~', 'normal', '(', 'mu', '1', ')']], [['y', '~', 'normal', '(', 'mu2', '1', ')']]]
[0]:
  [['x', '~', 'normal', '(', 'mu', '1', ')']]
  - model_definition: ['x', '~', 'normal', '(', 'mu', '1', ')']
    - random_variable_name: x
[1]:
  [['y', '~', 'normal', '(', 'mu2', '1', ')']]
  - model_definition: ['y', '~', 'normal', '(', 'mu2', '1', ')']
    - random_variable_name: y

在这两种情况下,我都看到完整内容被返回,因此我不理解您所说的“如果返回多个,则无法拆分每个子项”是什么意思。

但仍然存在一个问题-如果返回多个,则无法拆分每个子项。:/对谢谢你,我有一个类似的问题,它修复了它汉克斯保罗。我的意思是,它不再继续为
model\u definition
s的孩子们命名。我最终使用了
setParseAction
并返回(名称、令牌)。无论如何,我想我最终还是需要使用
setParseAction