当前位置: 首页>>技术问答>>正文


如何使用不同字符串分别替换一个字符串中的多个子字符串?

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

python string replace

参考资料

本文由《纯净天空》出品。文章地址: https://vimsky.com/article/3734.html,未经允许,请勿转载。