如何根据Python中的字典替换大字符串的子字符串?

如何根据Python中的字典替换大字符串的子字符串?,python,string,replace,Python,String,Replace,我有一个长字符串(“模板”),包含%MARK%形式的“替换点”(单个给定标记的字符串中也可能出现更多的替换点)。我想替换这些由Python字典控制的标记(它不包含标记的%符号),如: 问题:简单地逐个调用replace()方法不是一个好的解决方案:以前的替换可能包含这些标记中的一个,因此不能替换 解决方案应该足够快,因为我有大型模板,并且我需要在一个大循环中替换其中的许多模板。我有一个非常难看且很长的实现,有许多find(),在重放过程中计算原始字符串中的偏移量,等等。我希望有一个更好、更紧凑、

我有一个长字符串(“模板”),包含%MARK%形式的“替换点”(单个给定标记的字符串中也可能出现更多的替换点)。我想替换这些由Python字典控制的标记(它不包含标记的%符号),如:

问题:简单地逐个调用
replace()
方法不是一个好的解决方案:以前的替换可能包含这些标记中的一个,因此不能替换


解决方案应该足够快,因为我有大型模板,并且我需要在一个大循环中替换其中的许多模板。我有一个非常难看且很长的实现,有许多
find()
,在重放过程中计算原始字符串中的偏移量,等等。我希望有一个更好、更紧凑、更快的解决方案。

最简单的解决方案是

import re
re.sub(r'%(.+?)%', lambda m: rep_dict[m.group(1)], YOUR_TEMPLATE)

不够快?有人说“不要使用正则表达式”,你服从了吗?使用Python中的一些代码解析模板会更加复杂和缓慢(不要忘记,
re
是用C编写的)。

这非常好。我总是以没有时间学习RegEx为借口, 但我始终尊重它。这篇文章给了我必要的开始。这就是我的解决方案 但是,我发现组调用在字典参数中混淆了:

retVal          = re.sub(r'%title', theTitle, template)
retVal          = re.sub(r'%([a-z]+?)+', \
                    lambda m: myDict.get(m.group(0)[1:], ''), retVal)

title
不在词典中,这就是我为什么先这么做的原因。团队中其他人的要求。

谢谢,我不想故意避开regexp(这更像是我对Python有点初学者的情况)。。。这是一个很好且“优雅”的解决方案,但有一个小问题:模板可能包含一个标记,而该标记不在rep_dict中。在这种情况下,此解决方案会产生一个异常。如果rep_dict中没有替换信息,我需要返回字符串中未修改的%…%标记。如果要忽略无效标记,应使用
rep_dict.get(m.group(1),m.group())
而不是
rep_dict[m.group(1)]
。到目前为止,这是我最好的解决方案(里面有更多的实现细节):def_replace_by_dict(rep,s):s=re.split(([A-Z0-9]{1,32}%),s)用于rep.items中的A,b():用于范围内的c(len(s)):如果s[c]==“%”+A+“%”:s[c]=b return.join(s)它是在我问了这个问题之后,在我读你的答案之前写的。但是你的解决方案要优雅得多,只是我对“未处理的标记”有问题,正如我所提到的。你可以抓住keyrerror并
pass
Nice,你的评论现在帮助我理解了这一点。谢谢你的回答/评论!遗憾的是,您使用了%MARK%而不是{MARK},因为您可以在字典中使用传统的字符串格式。还有${MARK}或$MARK,您可以使用字符串模板。@joaquin您是指
%(MARK)
还是
{MARK}
%…
表示法已被弃用,
{…}
要求他将纯文本大括号加倍:
{{这些大括号到达输出字符串}},{这些不}
。不,我不是指
%
的插值(顺便说一句,尽管有人说,它还没有消失的日期)但是
string.Template
。我重新编辑并完成了我的评论
retVal          = re.sub(r'%title', theTitle, template)
retVal          = re.sub(r'%([a-z]+?)+', \
                    lambda m: myDict.get(m.group(0)[1:], ''), retVal)