使用替换字典替换字符串的最简单方法?


74

考虑..

dict = {
'Спорт':'Досуг',
'russianA':'englishA'
}

s = 'Спорт russianA'

我想用中的所有字典键替换它们各自的字典值s


1
这可能不是那么简单。您可能应该有一个显式的标记程序(例如{'cat': 'russiancat'}和“ caterpillar”)。还会重叠单词({'car':'russiancar', 'pet' : 'russianpet'}和“地毯”)。


2
dict顺便说一句:我认为最好避免使用变量名,因为此名称的变量会遮盖相同名称的内置函数。
jochen 2012年

Answers:


98

使用re:

import re

s = 'Спорт not russianA'
d = {
'Спорт':'Досуг',
'russianA':'englishA'
}

pattern = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b')
result = pattern.sub(lambda x: d[x.group()], s)
# Output: 'Досуг not englishA'

这只会匹配整个单词。如果不需要,请使用以下模式:

pattern = re.compile('|'.join(d.keys()))

请注意,在这种情况下,如果某些词典条目是其他条目的子字符串,则应按长度降序对单词进行排序。


24
如果字典键包含诸如“ ^”,“ $”和“ /”之类的字符,则在组合正则表达式之前需要对键进行转义。为此,.join(d.keys())可以用代替.join(re.escape(key) for key in d.keys())
jochen 2012年

请注意,第一个示例(Досуг不是englishA)仅适用于python3。在python2中,它仍然返回我“Спортnot englishA”
水果

当dict中的单词带有点时,它似乎失败了https://regex101.com/r/bliVUS/1--我需要\b在结尾处删除,但不确定它是否正确。
Peter.k,

25

您可以使用reduce函数:

reduce(lambda x, y: x.replace(y, dict[y]), dict, s)

16
与@Max Shawabkeh的解决方案不同,使用逐个reduce应用替换。结果,使用字典交换单词{ 'red': 'green', 'green': 'red'}不适用于reduce基于-的方法,并且重叠的匹配项以不可预测的方式转换。
jochen 2012年

2
一个很好的例子说明为什么重复.replace()通话可能会带来意想不到的后果:-html.replace('"', '"').replace('&', '&')尝试一下html = '"foo"'
zigg 2013年

ChristopheDuser2769207的答案所示的展开的循环相比,这不必要地复杂且难以理解

17

在这里找到解决方案(我喜欢它的简单性):

def multipleReplace(text, wordDict):
    for key in wordDict:
        text = text.replace(key, wordDict[key])
    return text

11
再次,正如@jochen所描述的,如果有一个键也是一个值,这将带来翻译错误的风险。单程替换将是最好的。
克里斯,

5

一种方法,无需重新

d = {
'Спорт':'Досуг',
'russianA':'englishA'
}

s = 'Спорт russianA'.split()
for n,i in enumerate(s):
    if i in d:
        s[n]=d[i]
print ' '.join(s)

3
如果dict的键中有空格,这将失败
Trinh Hoang Nhu

3

尽管是独立创建的,但几乎与ghostdog74相同。使用d.get()代替d []的一个区别是可以处理不在dict中的项目。

>>> d = {'a':'b', 'c':'d'}
>>> s = "a c x"
>>> foo = s.split()
>>> ret = []
>>> for item in foo:
...   ret.append(d.get(item,item)) # Try to get from dict, otherwise keep value
... 
>>> " ".join(ret)
'b d x'

1

我在类似的情况下使用了此字符串(我的字符串全部为大写):

def translate(string, wdict):
    for key in wdict:
        string = string.replace(key, wdict[key].lower())
    return string.upper()

希望以某种方式有所帮助... :)


2
这与ChristopheD的解决方案非常相似。你不同意他吗?
hynekcer 2013年

1

警告如果密钥有空间,它将失败,这是一个类似于ghostdog74和extaneons的压缩解决方案:

d = {
'Спорт':'Досуг',
'russianA':'englishA'
}

s = 'Спорт russianA'

' '.join(d.get(i,i) for i in s.split())
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.