pyparsing:组合多个元素的setResultsName
pyparsing: setResultsName for multiple elements get combined
这是我正在解析的文本:
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_definition
都被标记?如果 model_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
据我所知没有记录,但我在 pyparsing.py
:
中找到了一些东西
我将 .setResultsName('model_definition')
更改为 .setResultsName('model_definition*')
,它们正确列出了!
编辑:已记录,但它是您传递给 setResultsName
的标志:
setResultsName( string, listAllMatches=False ) - name to be given to tokens matching the element; if multiple tokens within a repetition group (such as ZeroOrMore or delimitedList) the default is to return only the last matching token - if listAllMatches is set to True, then a list of matching tokens is returned.
这里有足够的代码来运行:
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
缩写形式的情况,setResultsName
中存在尾随 '*'
:expr("name*")
与 expr.setResultsName("name", listAllMatches=True)
。如果您更喜欢调用 setResultsName
,那么我不会使用 '*'
表示法,但会传递 listAllMatches
参数。
如果您得到的名称相互重叠,您可能需要添加一个级别的分组。这是您使用 listAllMatches=True
的解决方案,凭借尾随 '*'
符号:
model_definition1 = model_definition('model_definition*')
print OneOrMore(model_definition1).parseString(sample).dump()
它returns这个解析结果:
[['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', ')']
这里有一个不使用listAllMatches
的变体,但添加了另一层Group:
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
在这两种情况下,我都看到了完整的内容被返回,所以我不会放弃理解你的意思"if you return multiple, it fails to split out each child."
这是我正在解析的文本:
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_definition
都被标记?如果 model_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
据我所知没有记录,但我在 pyparsing.py
:
我将 .setResultsName('model_definition')
更改为 .setResultsName('model_definition*')
,它们正确列出了!
编辑:已记录,但它是您传递给 setResultsName
的标志:
setResultsName( string, listAllMatches=False ) - name to be given to tokens matching the element; if multiple tokens within a repetition group (such as ZeroOrMore or delimitedList) the default is to return only the last matching token - if listAllMatches is set to True, then a list of matching tokens is returned.
这里有足够的代码来运行:
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
缩写形式的情况,setResultsName
中存在尾随 '*'
:expr("name*")
与 expr.setResultsName("name", listAllMatches=True)
。如果您更喜欢调用 setResultsName
,那么我不会使用 '*'
表示法,但会传递 listAllMatches
参数。
如果您得到的名称相互重叠,您可能需要添加一个级别的分组。这是您使用 listAllMatches=True
的解决方案,凭借尾随 '*'
符号:
model_definition1 = model_definition('model_definition*')
print OneOrMore(model_definition1).parseString(sample).dump()
它returns这个解析结果:
[['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', ')']
这里有一个不使用listAllMatches
的变体,但添加了另一层Group:
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
在这两种情况下,我都看到了完整的内容被返回,所以我不会放弃理解你的意思"if you return multiple, it fails to split out each child."