替换占位符字典键值的正则表达式问题
regex issues with replacing placeholders dictionary key values
这是对问题的引用:
我有占位符(与引用的问题相同,除了最后一个)。我需要替换占位符 $fil_TABLE_NAME1
,其中 $fil_
保持不变,但 table 名称不同(用下划线分隔,可以包含数字)
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101',
r'$fil_\w+': '(select * from table)'
}
为了替换,我使用了参考问题中调整后的代码
def remove_escape_chars(reggie):
return re.sub(r'\$\d\*|$\d*|\$fil\\_\\w\\+|\', '', reggie) #modification
def multiple_replace(escape_dict, text):
# Create a second dictionary to lookup regex match replacement targets
unescaped_placeholders = { remove_escape_chars(k): placeholders[k] for k in placeholders }
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(escape_dict.keys()))
return regex.sub(lambda match: unescaped_placeholders[remove_escape_chars(match.group(0))], text)
但是当我用
执行它时
text = "sometext $fil_SAMPLE_TABLE_NAME some more text $plc_hldr2 some more more text
1234date_placeholder some text 78date_placeholder"
result = multiple_replace(placeholders, text)
print(result)
我得到 sometext $fil_SAMPLE_TABLE_NAME some more text abcd some more more text 20200101 some text 20200101
- $fil_SAMPLE_TABLE_NAME
没有被替换。
我觉得我的正则表达式有问题,可能转义不正确,但经过多次修改后,我还是找不到问题。
有人能帮帮我吗?
对此我会采取稍微不同的方法。与其尝试匹配匹配部分字符串的正则表达式,不如创建一个正则表达式,在其自己的组中包含每个单独的正则表达式,然后使用匹配的组号查找替换值。对于您的示例数据,正则表达式如下所示:
($plc_hldr1)|($plc_hldr2)|($\d*date_placeholder)|($fil_\w+)
然后 python 代码将是:
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101',
r'$fil_\w+': '(select * from table)'
}
replacements = list(placeholders.values())
text = "sometext $fil_SAMPLE_TABLE_NAME some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder"
regex = re.compile('(' + ')|('.join(placeholders.keys()) + ')')
regex.sub(lambda m: replacements[m.lastindex-1], text)
输出:
sometext (select * from table) some more text abcd some more more text 20200101 some text 20200101
请注意,这要求任何占位符正则表达式中的任何组都必须是 non-capturing,即 (?:...)
而不是 (...)
。
这是对问题的引用:
我有占位符(与引用的问题相同,除了最后一个)。我需要替换占位符 $fil_TABLE_NAME1
,其中 $fil_
保持不变,但 table 名称不同(用下划线分隔,可以包含数字)
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101',
r'$fil_\w+': '(select * from table)'
}
为了替换,我使用了参考问题中调整后的代码
def remove_escape_chars(reggie):
return re.sub(r'\$\d\*|$\d*|\$fil\\_\\w\\+|\', '', reggie) #modification
def multiple_replace(escape_dict, text):
# Create a second dictionary to lookup regex match replacement targets
unescaped_placeholders = { remove_escape_chars(k): placeholders[k] for k in placeholders }
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(escape_dict.keys()))
return regex.sub(lambda match: unescaped_placeholders[remove_escape_chars(match.group(0))], text)
但是当我用
执行它时text = "sometext $fil_SAMPLE_TABLE_NAME some more text $plc_hldr2 some more more text
1234date_placeholder some text 78date_placeholder"
result = multiple_replace(placeholders, text)
print(result)
我得到 sometext $fil_SAMPLE_TABLE_NAME some more text abcd some more more text 20200101 some text 20200101
- $fil_SAMPLE_TABLE_NAME
没有被替换。
我觉得我的正则表达式有问题,可能转义不正确,但经过多次修改后,我还是找不到问题。
有人能帮帮我吗?
对此我会采取稍微不同的方法。与其尝试匹配匹配部分字符串的正则表达式,不如创建一个正则表达式,在其自己的组中包含每个单独的正则表达式,然后使用匹配的组号查找替换值。对于您的示例数据,正则表达式如下所示:
($plc_hldr1)|($plc_hldr2)|($\d*date_placeholder)|($fil_\w+)
然后 python 代码将是:
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101',
r'$fil_\w+': '(select * from table)'
}
replacements = list(placeholders.values())
text = "sometext $fil_SAMPLE_TABLE_NAME some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder"
regex = re.compile('(' + ')|('.join(placeholders.keys()) + ')')
regex.sub(lambda m: replacements[m.lastindex-1], text)
输出:
sometext (select * from table) some more text abcd some more more text 20200101 some text 20200101
请注意,这要求任何占位符正则表达式中的任何组都必须是 non-capturing,即 (?:...)
而不是 (...)
。