我想使用.replace函数替换多个字符串。
我目前有
string.replace("condition1", "")
但想要一些像
string.replace("condition1", "").replace("condition2", "text")
尽管这样的语法感觉不太好
正确的做法是什么?有点像在grep/regex中,你可以用\1和\2来替换某些搜索字符串的字段
我想使用.replace函数替换多个字符串。
我目前有
string.replace("condition1", "")
但想要一些像
string.replace("condition1", "").replace("condition2", "text")
尽管这样的语法感觉不太好
正确的做法是什么?有点像在grep/regex中,你可以用\1和\2来替换某些搜索字符串的字段
当前回答
我也在这个问题上苦苦挣扎。由于有很多替换,正则表达式比较吃力,大约比循环字符串慢四倍。替换(在我的实验条件)。
你绝对应该尝试使用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”),这种方法也很有效。
其他回答
在我的情况下,我需要一个简单的唯一键替换名称,所以我想到了这个:
a = 'This is a test string.'
b = {'i': 'I', 's': 'S'}
for x,y in b.items():
a = a.replace(x, y)
>>> a
'ThIS IS a teSt StrIng.'
下面是另一种使用字典的方法:
listA="The cat jumped over the house".split()
modify = {word:word for number,word in enumerate(listA)}
modify["cat"],modify["jumped"]="dog","walked"
print " ".join(modify[x] for x in listA)
我在学校作业中也做过类似的练习。这就是我的解
dictionary = {1: ['hate', 'love'],
2: ['salad', 'burger'],
3: ['vegetables', 'pizza']}
def normalize(text):
for i in dictionary:
text = text.replace(dictionary[i][0], dictionary[i][1])
return text
自己查看测试字符串上的结果
string_to_change = 'I hate salad and vegetables'
print(normalize(string_to_change))
你真的不应该这样做,但我觉得这太酷了:
>>> replacements = {'cond1':'text1', 'cond2':'text2'}
>>> cmd = 'answer = s'
>>> for k,v in replacements.iteritems():
>>> cmd += ".replace(%s, %s)" %(k,v)
>>> exec(cmd)
现在,答案是所有替换的结果
再说一次,这是非常俗气的,不是你应该经常使用的东西。但我很高兴知道如果你需要的话,你可以这样做。
下面是一个支持基本正则表达式替换的版本。主要的限制是表达式不能包含子组,并且可能存在一些边缘情况:
基于@bgusach和其他的代码
import re
class StringReplacer:
def __init__(self, replacements, ignore_case=False):
patterns = sorted(replacements, key=len, reverse=True)
self.replacements = [replacements[k] for k in patterns]
re_mode = re.IGNORECASE if ignore_case else 0
self.pattern = re.compile('|'.join(("({})".format(p) for p in patterns)), re_mode)
def tr(matcher):
index = next((index for index,value in enumerate(matcher.groups()) if value), None)
return self.replacements[index]
self.tr = tr
def __call__(self, string):
return self.pattern.sub(self.tr, string)
测试
table = {
"aaa" : "[This is three a]",
"b+" : "[This is one or more b]",
r"<\w+>" : "[This is a tag]"
}
replacer = StringReplacer(table, True)
sample1 = "whatever bb, aaa, <star> BBB <end>"
print(replacer(sample1))
# output:
# whatever [This is one or more b], [This is three a], [This is a tag] [This is one or more b] [This is a tag]
诀窍是通过位置来识别匹配的组。它不是超级高效(O(n)),但它是有效的。
index = next((index for index,value in enumerate(matcher.groups()) if value), None)
替换是一次完成的。