在Python中,如何在不翻译单个字符的情况下实现多重替换?

时间:2013-04-06 22:19:17

标签: python python-2.7

我正在尝试使用字典翻译多个字符串;但是,它总是取代每个角色,我不知道如何调整我的代码。

我的字典:

{"You're": "I'm", "We've": "you've", 'am': 'are', "We'll": "you'll", 'im': "you're",
"we'd": "you'd", 'our': 'your', 'You': 'I', 'Was': 'were', 'your': 'my', "you're":
"I'm", 'We': 'you', "I've": "you've", "we've": "you've", 'This': 'that', "we're":
"you're", 'you': 'I', 'was': 'were', 'me': 'you', 'we': 'you', 'I': 'you', 'c': 'see',
"I'd": "you'd", 'Were': 'was', "I'm": "you're", 'My': 'your', "I'll": "you'll", "we'll":
"you'll", 'this': 'that', 'Am': 'are', 'ur': "I'm", 'i': 'you', 'u': 'me', "We'd":
"you'd", 'were': 'was', 'Our': 'your', "i'm": "you're", 'my': 'your', 'Your': 'my',
"We're": "you're"}

我的代码:

def replace_all(text, dic):
    for i, j in dic.iteritems():
        text = text.replace(i, j)
    return text

以后称之为:

message = replace_all(message, dictionary)

是否可以替换字符串中的整个单词?我对python很新,所以任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:4)

如果你的替换品没有重叠,

Blender's answer就可以正常工作,但如果你有这样的替代品(你这样做):

{'I': 'you', 'you': 'I'}

然后再次替换先前的替换,这是不合需要的。他的答案的一个小扩展修复了:

import re

def replace_all(text, dic):
    words = sorted(dic, key=len, reverse=True)
    return re.sub('\\b(' + '|'.join(map(re.escape, words)) + ')\\b',
                  lambda m: dic[m.group(0)], text)

首先创建一个如下所示的正则表达式:

\b(you|I)\b

the re module documentation中所述,\b代表“字边界” 1 。因此,它只会匹配单词边界的内部部分。 |表示正则表达式的括号内部分中的多个选项。有必要对选项进行反向排序,因为Python会在第一个匹配时立即停止;如果I之前是I'm,那么它永远不会与I'm匹配,因为I始终在I'm之前匹配。

因此我们将该正则表达式传递给re.sub,它不仅可以替换替换字符串,还可以替换函数,这样可以实现更复杂的逻辑。我们的函数查找我们在字典中匹配的文本,并返回与该键相关联的值作为要替换的文本。

1 不幸的是,当涉及括号时,'word'的定义并不聪明,所以:

>>> replace_all("I'm not convinced.", {"I": "you"})
"you'm not convinced."

幸运的是,因为我们对它进行了排序,所以最长的匹配将始终首先发生:

>>> replace_all("I'm not convinced.", {"I": "you", "I'm": "you're"})
"you're not convinced."