用字典替换占位符 keys/values
Replacing placeholders with dictionary keys/values
我的文本包含如下占位符:
sometext $plc_hldr1 some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder
然后我有字典,其中键代表占位符,值是占位符应替换为的值:
placeholders = {'$plc_hldr1': '1111',
'$plc_hldr2': 'abcd'}
我找到并调整了处理替换的函数:
def multiple_replace(adict, text):
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(map(re.escape, adict.keys( ))))
# For each match, look up the corresponding value in the dictionary
return regex.sub(lambda match: adict[match.group(0)], text)
该函数正在为 $plc_hldr1
和 $plc_hldr2
执行它的工作。
但是有 34date_placeholder
和 78date_placeholder
- 两者都应替换为一个预定义的值。在那些情况下 date_placeholder
保持不变,但数字部分总是不同的。
我想到的是:
def multiple_replace(adict, text):
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(map(re.escape, adict.keys( ))))
regex = re.sub("$\d*date_placeholder", "20200101", txt)
# For each match, look up the corresponding value in the dictionary
return regex.sub(lambda match: adict[match.group(0)], text)
但是有没有更优雅的方法呢?如果我有更多的占位符,其中包含可变数字部分,应将其替换为相同的值(例如 $1234dname_placeholder、$1234age_placeholder)?
如果不需要转义其余占位符,您可以将 $\d*date_placeholder
与其余占位符结合使用。然后,创建第二个没有任何特殊正则表达式字符的字典,以便在查找替换正则表达式匹配项时使用。
map(re.escape, adict.keys())
在上面的代码中是必需的,因为占位符名称中有特殊的正则表达式字符 $
。我建议您自己添加特殊字符转义,并将您的 $\d*date_placeholder
查找添加为 placeholders
中的 key/value 对。这消除了将 re.escape
映射到您的键上的需要以及在 multiple_replace
函数中使用第二个替换的需要。
像这样...
import re
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101'}
def remove_escape_chars(reggie):
return re.sub(r'\$\d\*|$\d*|\', '', reggie)
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 $plc_hldr1 some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder"
result = multiple_replace(placeholders, text)
print(result)
这种方法的缺点是,如果您将新模式引入占位符,则必须更新 remove_escape_chars(...)
函数中的正则表达式。 (它将扩展到类似的模式,例如 34dname_placeholder
或 34age_placeholder
。)
我的文本包含如下占位符:
sometext $plc_hldr1 some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder
然后我有字典,其中键代表占位符,值是占位符应替换为的值:
placeholders = {'$plc_hldr1': '1111',
'$plc_hldr2': 'abcd'}
我找到并调整了处理替换的函数:
def multiple_replace(adict, text):
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(map(re.escape, adict.keys( ))))
# For each match, look up the corresponding value in the dictionary
return regex.sub(lambda match: adict[match.group(0)], text)
该函数正在为 $plc_hldr1
和 $plc_hldr2
执行它的工作。
但是有 34date_placeholder
和 78date_placeholder
- 两者都应替换为一个预定义的值。在那些情况下 date_placeholder
保持不变,但数字部分总是不同的。
我想到的是:
def multiple_replace(adict, text):
# Create a regular expression from all of the dictionary keys
regex = re.compile("|".join(map(re.escape, adict.keys( ))))
regex = re.sub("$\d*date_placeholder", "20200101", txt)
# For each match, look up the corresponding value in the dictionary
return regex.sub(lambda match: adict[match.group(0)], text)
但是有没有更优雅的方法呢?如果我有更多的占位符,其中包含可变数字部分,应将其替换为相同的值(例如 $1234dname_placeholder、$1234age_placeholder)?
如果不需要转义其余占位符,您可以将 $\d*date_placeholder
与其余占位符结合使用。然后,创建第二个没有任何特殊正则表达式字符的字典,以便在查找替换正则表达式匹配项时使用。
map(re.escape, adict.keys())
在上面的代码中是必需的,因为占位符名称中有特殊的正则表达式字符 $
。我建议您自己添加特殊字符转义,并将您的 $\d*date_placeholder
查找添加为 placeholders
中的 key/value 对。这消除了将 re.escape
映射到您的键上的需要以及在 multiple_replace
函数中使用第二个替换的需要。
像这样...
import re
placeholders = {r'$plc_hldr1': '1111',
r'$plc_hldr2': 'abcd',
r'$\d*date_placeholder': '20200101'}
def remove_escape_chars(reggie):
return re.sub(r'\$\d\*|$\d*|\', '', reggie)
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 $plc_hldr1 some more text $plc_hldr2 some more more text 34date_placeholder some text 78date_placeholder"
result = multiple_replace(placeholders, text)
print(result)
这种方法的缺点是,如果您将新模式引入占位符,则必须更新 remove_escape_chars(...)
函数中的正则表达式。 (它将扩展到类似的模式,例如 34dname_placeholder
或 34age_placeholder
。)