Dies ist möglicherweise nicht so einfach. Sie sollten wahrscheinlich einen expliziten Tokenizer haben (zum Beispiel {'cat': 'russiancat'}und "Raupe"). Auch überlappende Wörter ( {'car':'russiancar', 'pet' : 'russianpet'}und "Teppich").
Nebenbei: Ich denke, es dictwird am besten als Variablenname vermieden, da eine Variable dieses Namens die integrierte Funktion mit demselben Namen beschatten würde.
Jochen
Antworten:
98
Verwenden von 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'
Dies entspricht nur ganzen Wörtern. Wenn Sie das nicht brauchen, verwenden Sie das Muster:
pattern = re.compile('|'.join(d.keys()))
Beachten Sie, dass Sie in diesem Fall die absteigenden Wörter nach Länge sortieren sollten, wenn einige Ihrer Wörterbucheinträge Teilzeichenfolgen anderer sind.
Falls die Wörterbuchschlüssel Zeichen wie "^", "$" und "/" enthalten, müssen die Schlüssel maskiert werden, bevor der reguläre Ausdruck zusammengestellt wird. Zu diesem Zweck .join(d.keys())könnte durch ersetzt werden .join(re.escape(key) for key in d.keys()).
Jochen
Bitte beachten Sie, dass das erste Beispiel (englосуг nicht englishA) nur in Python3 funktioniert. In Python2 gibt es mir immer noch "Спорт not englishA"
Fruit
Es scheint zu scheitern, wenn das Wort im Diktat einen Punkt hat - https://regex101.com/r/bliVUS/1- Ich muss es \bam Ende entfernen, bin mir aber nicht sicher, ob es korrekt ist.
Anders als bei der Lösung von @Max Shawabkeh werden reducebei der Verwendung die Substitutionen nacheinander angewendet . Infolgedessen { 'red': 'green', 'green': 'red'}funktioniert das Austauschen von Wörtern mithilfe von Wörterbüchern nicht mit dem reducebasierenden Ansatz, und überlappende Übereinstimmungen werden auf unvorhersehbare Weise transformiert.
Jochen
2
Ein gutes Beispiel dafür, warum wiederholte .replace()Anrufe unbeabsichtigte Folgen haben können: - html.replace('"', '"').replace('&', '&')Versuchen Sie es weiter html = '"foo"'.
Zigg
Dies ist unnötig komplex und unlesbar im Vergleich zu der entfalteten Schleife, wie in den Antworten von ChristopheD oder user2769207 gezeigt .
Wie @jochen beschrieben hat, riskiert dies wiederum eine schlechte Übersetzung, wenn es einen Schlüssel gibt, der auch ein Wert ist. Ein Single-Pass-Ersatz wäre am besten.
Chris
5
ein Weg, ohne re
d = {
'Спорт':'Досуг',
'russianA':'englishA'
}
s = 'Спорт russianA'.split()
for n,i in enumerate(s):
if i in d:
s[n]=d[i]
print' '.join(s)
Dies wird fehlschlagen, wenn das Diktat Platz in seinen Schlüsseln hat
Trinh Hoang Nhu
3
Fast das gleiche wie Ghostdog74, obwohl unabhängig erstellt. Ein Unterschied besteht darin, dass die Verwendung von d.get () anstelle von d [] Elemente verarbeiten kann, die nicht im Diktat enthalten sind.
>>> 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'
Es ist der Lösung von ChristopheD sehr ähnlich. Stimmen Sie ihm nicht zu?
Hynekcer
1
Mit der Warnung, dass es fehlschlägt, wenn der Schlüssel über Speicherplatz verfügt, handelt es sich um eine komprimierte Lösung, die der Antwort von ghostdog74 und extaneons ähnelt:
d = {
'Спорт':'Досуг',
'russianA':'englishA'
}
s = 'Спорт russianA'' '.join(d.get(i,i) for i in s.split())
{'cat': 'russiancat'}
und "Raupe"). Auch überlappende Wörter ({'car':'russiancar', 'pet' : 'russianpet'}
und "Teppich").dict
wird am besten als Variablenname vermieden, da eine Variable dieses Namens die integrierte Funktion mit demselben Namen beschatten würde.Antworten:
Verwenden von 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'
Dies entspricht nur ganzen Wörtern. Wenn Sie das nicht brauchen, verwenden Sie das Muster:
pattern = re.compile('|'.join(d.keys()))
Beachten Sie, dass Sie in diesem Fall die absteigenden Wörter nach Länge sortieren sollten, wenn einige Ihrer Wörterbucheinträge Teilzeichenfolgen anderer sind.
quelle
.join(d.keys())
könnte durch ersetzt werden.join(re.escape(key) for key in d.keys())
.https://regex101.com/r/bliVUS/1
- Ich muss es\b
am Ende entfernen, bin mir aber nicht sicher, ob es korrekt ist.Sie können die Reduktionsfunktion verwenden:
reduce(lambda x, y: x.replace(y, dict[y]), dict, s)
quelle
reduce
bei der Verwendung die Substitutionen nacheinander angewendet . Infolgedessen{ 'red': 'green', 'green': 'red'}
funktioniert das Austauschen von Wörtern mithilfe von Wörterbüchern nicht mit demreduce
basierenden Ansatz, und überlappende Übereinstimmungen werden auf unvorhersehbare Weise transformiert..replace()
Anrufe unbeabsichtigte Folgen haben können: -html.replace('"', '"').replace('&', '&')
Versuchen Sie es weiterhtml = '"foo"'
.Hier gefundene Lösung (ich mag die Einfachheit):
def multipleReplace(text, wordDict): for key in wordDict: text = text.replace(key, wordDict[key]) return text
quelle
ein Weg, ohne re
d = { 'Спорт':'Досуг', 'russianA':'englishA' } s = 'Спорт russianA'.split() for n,i in enumerate(s): if i in d: s[n]=d[i] print ' '.join(s)
quelle
Fast das gleiche wie Ghostdog74, obwohl unabhängig erstellt. Ein Unterschied besteht darin, dass die Verwendung von d.get () anstelle von d [] Elemente verarbeiten kann, die nicht im Diktat enthalten sind.
>>> 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'
quelle
Ich habe dies in einer ähnlichen Situation verwendet (meine Zeichenfolge war alle in Großbuchstaben):
def translate(string, wdict): for key in wdict: string = string.replace(key, wdict[key].lower()) return string.upper()
hoffe das hilft irgendwie ... :)
quelle
Mit der Warnung, dass es fehlschlägt, wenn der Schlüssel über Speicherplatz verfügt, handelt es sich um eine komprimierte Lösung, die der Antwort von ghostdog74 und extaneons ähnelt:
d = { 'Спорт':'Досуг', 'russianA':'englishA' } s = 'Спорт russianA' ' '.join(d.get(i,i) for i in s.split())
quelle