我想使用.replace函数来替换多个字符串。
我现在有
string.replace("condition1", "")
但想要有类似下面这样多次替换的东西
string.replace("condition1", "").replace("condition2", "text")
虽然这不觉得好的语法
什么是正确的方法来做到这一点?有点像在grep /regex中你可以做\1
和\2
来替换字段到某些搜索字符串
最佳解决方法
这里是一个简短的例子,应该用正则表达式来实现:
import re
rep = {"condition1": "", "condition2": "text"} # define desired replacements here
# use these three lines to do the replacement
rep = dict((re.escape(k), v) for k, v in rep.iteritems())
pattern = re.compile("|".join(rep.keys()))
text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)
例如:
>>> pattern.sub(lambda m: rep[re.escape(m.group(0))], "(condition1) and --condition2--")
'() and --text--'
次佳解决方法
你可以做一个漂亮的小循环函数。
def replace_all(text, dic):
for i, j in dic.iteritems():
text = text.replace(i, j)
return text
其中text
是完整的字符串,dic
是一个字典 – 每个定义是一个字符串,将替换匹配的术语。
注意:在Python 3中,iteritems()
已被替换为items()
小心:请注意,这个答案要求:
-
替换是顺序无关的
-
每次替换都可以更改以前替换的结果
这是因为python字典没有可靠的迭代顺序。
例如,如果一本字典有:
{ "cat": "dog", "dog": "pig"}
和字符串是:
"This is my cat and this is my dog."
我们不一定知道首先使用哪个字典条目,结果是:
"This is my pig and this is my pig."
或者
"This is my dog and this is my pig."
记住text
字符串有多大以及字典中有多少对是有效的。
第三种解决方法
这是使用reduce的第一个解决方案的一个变体,如果你喜欢函数式编程。 🙂
repls = {'hello' : 'goodbye', 'world' : 'earth'}
s = 'hello, world'
reduce(lambda a, kv: a.replace(*kv), repls.iteritems(), s)
更好的版本:
repls = ('hello', 'goodbye'), ('world', 'earth')
s = 'hello, world'
reduce(lambda a, kv: a.replace(*kv), repls, s)
第四种方法
一个不错的答案:
import re
def multiple_replacer(*key_values):
replace_dict = dict(key_values)
replacement_function = lambda match: replace_dict[match.group(0)]
pattern = re.compile("|".join([re.escape(k) for k, v in key_values]), re.M)
return lambda string: pattern.sub(replacement_function, string)
def multiple_replace(string, *key_values):
return multiple_replacer(*key_values)(string)
一次性用法:
>>> replacements = (u"café", u"tea"), (u"tea", u"café"), (u"like", u"love")
>>> print multiple_replace(u"Do you like café? No, I prefer tea.", *replacements)
Do you love tea? No, I prefer café.
请注意,由于替换只需一次,”café”更改为”tea”,但不会更改回”café”。
如果您需要多次进行相同的替换,则可以轻松创建替换功能:
>>> my_escaper = multiple_replacer(('"','\\"'), ('\t', '\\t'))
>>> many_many_strings = (u'This text will be escaped by "my_escaper"',
u'Does this work?\tYes it does',
u'And can we span\nmultiple lines?\t"Yes\twe\tcan!"')
>>> for line in many_many_strings:
... print my_escaper(line)
...
This text will be escaped by \"my_escaper\"
Does this work?\tYes it does
And can we span
multiple lines?\t\"Yes\twe\tcan!\"
改进:
-
把代码转换成一个函数
-
增加了多行支持
-
修复了escaping中的BUG
-
容易为特定的多个替换创建功能
第五种方法
这是一个更简洁的回顾。实现同时替换多个字符串使用以下的函数即可:
import re
def multiple_replace(string, rep_dict):
pattern = re.compile("|".join([re.escape(k) for k in rep_dict.keys()]), re.M)
return pattern.sub(lambda x: rep_dict[x.group(0)], string)
用法:
>>>multiple_replace("Do you like cafe? No, I prefer tea.", {'cafe':'tea', 'tea':'cafe', 'like':'prefer'})
'Do you prefer tea? No, I prefer cafe.'
如果你愿意,你可以从这个简单的开始,做出你自己的专用替换函数。
第六种方法
我想提出使用字符串模板。只需将字符串放在一个字典中,全部设置!来自docs.python.org的示例
>>> from string import Template
>>> s = Template('$who likes $what')
>>> s.substitute(who='tim', what='kung pao')
'tim likes kung pao'
>>> d = dict(who='tim')
>>> Template('Give $who $100').substitute(d)
Traceback (most recent call last):
[...]
ValueError: Invalid placeholder in string: line 1, col 10
>>> Template('$who likes $what').substitute(d)
Traceback (most recent call last):
[...]
KeyError: 'what'
>>> Template('$who likes $what').safe_substitute(d)
'tim likes $what'