我想使用.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'