嵌套括号字符串需要从最内部函数到外部函数进行计算

问题描述 投票:0回答:1

使用给定的字符串

exp = 'FILLDOWN(IF(MATCHES([F1], "*Sub-String"), "1", ""))'

我想用下面字典中提到的表达式替换每个函数

# Function with its corresponding expression
function_mapping = {
'FILLDOWN': 'IF IsNull([$1]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[$1] EndIF',
'IF': 'IF $1 Then $2 Else $3 EndIF',
'MATCHES': 'IF Contains($2, $1) Then 1 else 0 Endif'
}

替换顺序是从最里面的函数到最外面的函数,依此类推。 因此,对于给定的

exp
字符串,我需要识别最内部的函数并替换它,并将其输出存储到另一个变量中,然后将其输入到其直接外部函数

例如这里最内部的函数是

MATCHES
,因此使用字典中给出的相应表达式值替换它
function_mapping

步骤:

  1. MATCHES
    将替换为
    firstVar = IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif
    这里 $1 和 $2 将替换为
    MATCHES
    exp
  2. 的参数
  3. 找到下一个最里面的函数,即
    IF
    将被替换为
    secondVar = IF firstVar Then "1" Else "" EndIF
  4. 找到下一个最内部的函数,即
    FILLDOWN
    将替换为
    thirdVar = IF IsNull([secondVar]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[secondVar] EndIF

最终输出将是字符串:

final = """
firstVar = IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif
secondVar = IF firstVar Then "1" Else "" EndIF
thirdVar = IF IsNull([secondVar]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[secondVar] EndIF
"""
python data-structures tree recursive-datastructures
1个回答
0
投票

一个想法是获取最里面的函数并替换它。重复此操作,直到无法再完成为止。问题是被替换的函数可能有它自己的函数,从而创建一个新的最内层函数。解决方案是用特殊字符串(即 $1、$2 等)替换。然后最后将这些特殊字符串替换为实际应该的字符串。

  import re 
  exp = 'FILLDOWN(IF(MATCHES([F1], "*Sub-String"), "1", ""))'
  function_mapping = {
        'FILLDOWN': 'IF IsNull([$1]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[$1] EndIF',
        'IF': 'IF $1 Then $2 Else $3 EndIF',
        'MATCHES': 'IF Contains($2, $1) Then 1 else 0 Endif'
    }

def get_inner(exp):
    return list(re.finditer(r"([A-Za-z\_]+)(\([^\(]*?\))", exp))
    
def replace_args(func, args):
    n = len(args)
    replacement = function_mapping[func]
    for i in range(n):
        replacement = re.sub(f"\${i+1}", args[i], replacement)
    return replacement

count = 0
replacements = {}

while True:
    matches = get_inner(exp)

    if not matches:
        break

    for m in matches:
        g = m.groups()
        func, args = g[0], re.sub(r"[\(\)\s]", "", g[1]).split(",")

        replacement = replace_args(func, args)
        replacements[f"${count}"] = replacement
        
        exp = re.sub(re.escape(g[0]+g[1]), f"${count}", exp)
        print(exp)
        count += 1


print()
for k,v in replacements.items():
    print(f"{k}: {v}")
print()

n = len(replacements)
for i in reversed(range(n)):
    pattern = f"${i}"
    exp = re.sub(re.escape(pattern), replacements[pattern], exp)
    print(f"{exp}\n")

给你这个输出:

FILLDOWN(IF($0, "1", ""))
FILLDOWN($1)
$2

$0: IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif
$1: IF $0 Then "1" Else "" EndIF
$2: IF IsNull([$1]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[$1] EndIF

IF IsNull([$1]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[$1] EndIF

IF IsNull([IF $0 Then "1" Else "" EndIF]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[IF $0 Then "1" Else "" EndIF] EndIF

IF IsNull([IF IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif Then "1" Else "" EndIF]) Then [Row-1:__$ITEMID_COL_NAME$__] Else[IF IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif Then "1" Else "" EndIF] EndIF
© www.soinside.com 2019 - 2024. All rights reserved.