Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 解析字符串中的嵌套引用_Python_Pyparsing - Fatal编程技术网

Python 解析字符串中的嵌套引用

Python 解析字符串中的嵌套引用,python,pyparsing,Python,Pyparsing,上下文 在Python中,给定的是一个包含嵌套的点符号引用的任意字符串,稍后将用实际值替换 str='Allocate{ref:network.node.{ref:global.environment}.api}与{ref:local.value} 引用需要由内而外进行替换,因此首先要替换ref:global.environment='prod',然后再替换ref:network.node.prod.api=''/prod/api',ref:local.value='UUID',因此结果是:

上下文

在Python中,给定的是一个包含嵌套的点符号引用的任意字符串,稍后将用实际值替换

str='Allocate{ref:network.node.{ref:global.environment}.api}与{ref:local.value}
引用需要由内而外进行替换,因此首先要替换ref:global.environment='prod',然后再替换ref:network.node.prod.api=''/prod/api',ref:local.value='UUID',因此结果是:

result='Allocate/prod/api with UUID'
解析

试图用pyparsing解决这个问题,因为regex在嵌套引用中有点丢失。目标是有一个引用列表,我可以在以后的步骤中处理/替换这些引用

lbrack='{ref:'
rbrack='}'
ref=Forward()

ref如果您可以执行扫描并替换自己,您可以执行类似的操作(仅使用简单的字典插入值作为示例):


显然,它需要扩展以处理不属于引用一部分的大括号(如果它们可能存在于您正在处理的字符串中),并且我没有包括错误检查,例如,不匹配的大括号或对未知值的引用。

您在正确的轨道上,但我需要帮助你解决一个共同的基本问题

当人们使用以下方法定义合格标识符时,我经常看到这一点:

Word(alphas, alphanums + ".")
它有一些固有的问题,因为它不仅会匹配“a”和“a.b.c.d”,而且还会匹配“a.”、“a…”、“a.c.”和“a.c.0.”作为标识符。在您的例子中,您还希望支持嵌入的ref来代替限定标识符

因此,不妨这样想:

qualified_ident ::= ident_term ["." ident_term]...
ident_term := reference | identifier
reference := "{ref:" qualified_ident "}"
identifier := "A-Za-z" "A-Za-z0-9"...
现在,您的限定标识可以由引用组成,引用本身也可以由限定标识组成

在pyparsing中,这看起来像(使用带“.delim”的分隔列表作为限定标识):

现在,我们将编写一个解析操作,该操作将使用以下名称空间dict计算引用的路径:

def eval_ref(tokens):
    ret = ns

    # uncomment for debugging
    # print(tokens[0])

    # resolve next level down in the reference path
    for t in tokens[0][1:-1]:
        ret = ret[t]
    return ret

# and add as a parse action to ref
ref.addParseAction(eval_ref)
应该可以了,让我们在测试字符串上尝试一下(我重命名了它,因为
str
是Python中的内置类型,不适合用变量名来屏蔽它)。我们将使用
transformString
而不是
parseString
transformString
将用任何解析操作发出的文本替换任何源文本(或者如果包装为Suppress,则为Suppress),这将递归地发生在您身上,这样您的内部引用将得到计算,然后外部引用将使用该内部解析值进行计算

test = 'Allocate {ref:network.node.{ref:global.environment}.api} with {ref:local.value}'
print(ref.transformString(test))
应提供:

Allocate prod_api with 1000

很漂亮,很有魅力,感谢您的详细解释,这有助于理解和传递解析背后的内容。
def eval_ref(tokens):
    ret = ns

    # uncomment for debugging
    # print(tokens[0])

    # resolve next level down in the reference path
    for t in tokens[0][1:-1]:
        ret = ret[t]
    return ret

# and add as a parse action to ref
ref.addParseAction(eval_ref)
test = 'Allocate {ref:network.node.{ref:global.environment}.api} with {ref:local.value}'
print(ref.transformString(test))
Allocate prod_api with 1000