使用给定的字符串
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
步骤:
MATCHES
将替换为 firstVar = IF Contains("*Sub-String", [F1]) Then 1 else 0 Endif
这里 $1 和 $2 将替换为 MATCHES
中
exp
IF
将被替换为secondVar = IF firstVar Then "1" Else "" EndIF
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
"""
一个想法是获取最里面的函数并替换它。重复此操作,直到无法再完成为止。问题是被替换的函数可能有它自己的函数,从而创建一个新的最内层函数。解决方案是用特殊字符串(即 $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