我想使用.replace函数替换多个字符串。

我目前有

string.replace("condition1", "")

但想要一些像

string.replace("condition1", "").replace("condition2", "text")

尽管这样的语法感觉不太好

正确的做法是什么?有点像在grep/regex中,你可以用\1和\2来替换某些搜索字符串的字段


当前回答

我觉得这个问题需要一个单行递归lambda函数的答案,只是因为。所以有:

>>> mrep = lambda s, d: s if not d else mrep(s.replace(*d.popitem()), d)

用法:

>>> mrep('abcabc', {'a': '1', 'c': '2'})
'1b21b2'

注:

这将消耗输入字典。 Python字典保留3.6起的键顺序;其他答案中的相应警告不再相关。为了向后兼容,可以使用基于元组的版本:

>>> mrep = lambda s, d: s if not d else mrep(s.replace(*d.pop()), d)
>>> mrep('abcabc', [('a', '1'), ('c', '2')])

注意:与python中的所有递归函数一样,太大的递归深度(即替换字典太大)将导致错误。请看这里。

其他回答

我觉得这个问题需要一个单行递归lambda函数的答案,只是因为。所以有:

>>> mrep = lambda s, d: s if not d else mrep(s.replace(*d.popitem()), d)

用法:

>>> mrep('abcabc', {'a': '1', 'c': '2'})
'1b21b2'

注:

这将消耗输入字典。 Python字典保留3.6起的键顺序;其他答案中的相应警告不再相关。为了向后兼容,可以使用基于元组的版本:

>>> mrep = lambda s, d: s if not d else mrep(s.replace(*d.pop()), d)
>>> mrep('abcabc', [('a', '1'), ('c', '2')])

注意:与python中的所有递归函数一样,太大的递归深度(即替换字典太大)将导致错误。请看这里。

你真的不应该这样做,但我觉得这太酷了:

>>> replacements = {'cond1':'text1', 'cond2':'text2'}
>>> cmd = 'answer = s'
>>> for k,v in replacements.iteritems():
>>>     cmd += ".replace(%s, %s)" %(k,v)
>>> exec(cmd)

现在,答案是所有替换的结果

再说一次,这是非常俗气的,不是你应该经常使用的东西。但我很高兴知道如果你需要的话,你可以这样做。

您可以使用pandas库和replace函数,它既支持精确匹配,也支持正则表达式替换。例如:

df = pd.DataFrame({'text': ['Billy is going to visit Rome in November', 'I was born in 10/10/2010', 'I will be there at 20:00']})

to_replace=['Billy','Rome','January|February|March|April|May|June|July|August|September|October|November|December', '\d{2}:\d{2}', '\d{2}/\d{2}/\d{4}']
replace_with=['name','city','month','time', 'date']

print(df.text.replace(to_replace, replace_with, regex=True))

修改后的文本为:

0    name is going to visit city in month
1                      I was born in date
2                 I will be there at time

你可以在这里找到一个例子。请注意,文本上的替换是按照它们在列表中出现的顺序进行的

另一个例子: 输入列表

error_list = ['[br]', '[ex]', 'Something']
words = ['how', 'much[ex]', 'is[br]', 'the', 'fish[br]', 'noSomething', 'really']

期望的输出将是

words = ['how', 'much', 'is', 'the', 'fish', 'no', 'really']

代码:

[n[0][0] if len(n[0]) else n[1] for n in [[[w.replace(e,"") for e in error_list if e in w],w] for w in words]] 

我也在这个问题上苦苦挣扎。由于有很多替换,正则表达式比较吃力,大约比循环字符串慢四倍。替换(在我的实验条件)。

你绝对应该尝试使用Flashtext库(博客文章在这里,Github在这里)。在我的例子中,每个文档的速度快了两个数量级,从1.8秒到0.015秒(正则表达式需要7.7秒)。

在上面的链接中很容易找到使用示例,但这是一个工作示例:

    from flashtext import KeywordProcessor
    self.processor = KeywordProcessor(case_sensitive=False)
    for k, v in self.my_dict.items():
        self.processor.add_keyword(k, v)
    new_string = self.processor.replace_keywords(string)

注意,Flashtext在一次传递中进行替换(以避免a -> b和b -> c将'a'转换为'c')。Flashtext也会查找整个单词(所以'is'不会匹配'this')。如果你的目标是几个单词(将“This is”替换为“Hello”),这种方法也很有效。