1

我正在尝试使用字典翻译多个字符串;但是,它总是替换每个单独的字符,而且我不知道如何调整我的代码。

我的字典:

{"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很陌生,所以任何帮助将不胜感激!

4

1 回答 1

4

如果您的替代品没有重叠, Blender 的答案就可以正常工作,但是如果您有这样的替代品(您可以这样做):

{'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

模块文档中所述re\b代表“单词边界” 1。因此,它只会匹配单词边界的内部部分。|表示正则表达式括号内的多项选择。有必要对长度选项进行反向排序,因为 Python 将在第一个匹配时立即停止;如果I是 before ,比如说 ,I'm那么它永远不会匹配I'm,因为I总是匹配 before I'm

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

1不幸的是,当涉及到括号时,“单词”的定义并不明智,因此:

>>> 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."
于 2013-04-06T22:28:03.703 回答