Ich möchte die .replace-Funktion verwenden, um mehrere Zeichenfolgen zu ersetzen.
Ich habe derzeit
string.replace("condition1", "")
möchte aber so etwas haben
string.replace("condition1", "").replace("condition2", "text")
obwohl sich das nicht nach guter Syntax anfühlt
Was ist der richtige Weg, um dies zu tun? Art wie wie in grep / regex Sie tun können , \1
und \2
Felder auf bestimmte Suchzeichenketten zu ersetzen
Antworten:
Hier ist ein kurzes Beispiel, das den Trick mit regulären Ausdrücken machen sollte:
Beispielsweise:
quelle
"spamham sha".replace("spam", "eggs").replace("sha","md5")
ist ,"eggmd5m md5"
statt"eggsham md5"
Sie könnten einfach eine nette kleine Schleifenfunktion machen.
Dabei
text
handelt es sich um die vollständige Zeichenfolge unddic
ein Wörterbuch. Jede Definition ist eine Zeichenfolge, die eine Übereinstimmung mit dem Begriff ersetzt.Hinweis : In Python 3
iteritems()
wurde durch ersetztitems()
Achtung: Python-Wörterbücher haben keine zuverlässige Reihenfolge für die Iteration. Diese Lösung löst Ihr Problem nur, wenn:
Zum Beispiel:
Mögliche Ausgabe Nr. 1:
Mögliche Ausgabe # 2
Eine mögliche Lösung ist die Verwendung eines OrderedDict.
Ausgabe:
Vorsicht # 2: Ineffizient, wenn Ihre
text
Zeichenfolge zu groß ist oder das Wörterbuch viele Paare enthält.quelle
OrderedDict
- oder eine Liste mit 2 Tupeln verwenden.Warum nicht eine solche Lösung?
quelle
Hier ist eine Variante der ersten Lösung mit Reduce, falls Sie funktionsfähig sein möchten. :) :)
Martineaus noch bessere Version:
quelle
repls
eine Folge von Tupeln zu erstellen und deniteritems()
Anruf zu beenden. dhrepls = ('hello', 'goodbye'), ('world', 'earth')
undreduce(lambda a, kv: a.replace(*kv), repls, s)
. Würde auch unverändert in Python 3reduce
es entfernt wurde .reduce
existiert noch, wurde jedoch in Python 3 zu einem Teil desfunctools
Moduls (siehe Dokumentation ) gemacht. Als ich also unverändert sagte, meinte ich, dass derselbe Code ausgeführt werden könnte - obwohl dies zugegebenermaßen erfordern würde, dassreduce
erimport
bei Bedarf bearbeitet wurde da es nicht mehr eingebaut ist.Dies ist nur eine präzisere Zusammenfassung der großartigen Antworten von FJ und MiniQuark. Alles, was Sie benötigen, um mehrere Zeichenfolgen gleichzeitig zu ersetzen, ist die folgende Funktion:
Verwendungszweck:
Wenn Sie möchten, können Sie ausgehend von dieser einfacheren Funktion Ihre eigenen Ersatzfunktionen erstellen.
quelle
rep_dict = {"but": "mut", "mutton": "lamb"}
der Zeichenfolge"button"
ergibt sich"mutton"
Ihr Code, aber würde geben,"lamb"
wenn die Ersetzungen nacheinander verkettet würden .Do you prefer cafe? No, I prefer cafe.
, was überhaupt nicht wünschenswert ist.Ich habe dies auf FJs ausgezeichneter Antwort aufgebaut:
One-Shot-Verwendung:
Da der Austausch in nur einem Durchgang erfolgt, ändert sich "Café" in "Tee", jedoch nicht wieder in "Café".
Wenn Sie denselben Austausch mehrmals durchführen müssen, können Sie einfach eine Ersatzfunktion erstellen:
Verbesserungen:
Genießen! :-)
quelle
pattern.sub
dass eine Funktion mit nur einem Parameter (dem zu ersetzenden Text) erwartet wird, sodass die Funktion Zugriff haben mussreplace_dict
.re.M
Ermöglicht mehrzeilige Ersetzungen (dies wird im Dokument gut erklärt: docs.python.org/2/library/re.html#re.M ).Ich möchte die Verwendung von Zeichenfolgenvorlagen vorschlagen. Platzieren Sie einfach die zu ersetzende Zeichenfolge in einem Wörterbuch und alles ist festgelegt! Beispiel aus docs.python.org
quelle
substitute
eine Ausnahme ausgelöst. Seien Sie also vorsichtig, wenn Sie Vorlagen von Benutzern erhalten.In meinem Fall brauchte ich ein einfaches Ersetzen eindeutiger Schlüssel durch Namen, also dachte ich mir Folgendes aus:
quelle
i
mits
Ihnen würde ein seltsames Verhalten bekommen.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
Wenn Sie Ihre Array-Paare sorgfältig bestellen, können Sie sicherstellen, dass Sie () nicht rekursiv ersetzen.Ab
Python 3.8
und Einführung von Zuweisungsausdrücken (PEP 572) (:=
Operator) können wir die Ersetzungen innerhalb eines Listenverständnisses anwenden:quelle
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Der Zuweisungsausdruck (text := text.replace
) erstellt aber auch iterativ neue Versionen von,text
indem er ihn mutiert. Nach dem Listenverständnis können Sie dietext
Variable verwenden, die den geänderten Text enthält.text
als Einzeiler zurückgeben möchten , können Sie auch[text := text.replace(a, b) for a, b in replacements][-1]
(beachten Sie das[-1]
) verwenden, das das letzte Element des Listenverständnisses extrahiert. dh die letzte Version vontext
.Hier meine $ 0,02. Es basiert auf Andrew Clarks Antwort, die nur ein wenig klarer ist, und deckt auch den Fall ab, dass eine zu ersetzende Zeichenfolge eine Teilzeichenfolge einer anderen zu ersetzenden Zeichenfolge ist (längere Zeichenfolge gewinnt).
In diesem Kern können Sie es jederzeit ändern, wenn Sie einen Vorschlag haben.
quelle
Ich brauchte eine Lösung, bei der die zu ersetzenden Zeichenfolgen reguläre Ausdrücke sein können, um beispielsweise einen langen Text zu normalisieren, indem mehrere Leerzeichen durch ein einzelnes ersetzt werden. Aufbauend auf einer Reihe von Antworten anderer, einschließlich MiniQuark und mmj, habe ich mir Folgendes ausgedacht:
Es funktioniert für die Beispiele in anderen Antworten, zum Beispiel:
Die Hauptsache für mich ist, dass Sie auch reguläre Ausdrücke verwenden können, um beispielsweise nur ganze Wörter zu ersetzen oder Leerzeichen zu normalisieren:
Wenn Sie die Wörterbuchschlüssel als normale Zeichenfolgen verwenden möchten, können Sie diese vor dem Aufruf von multiple_replace mit folgender Funktion umgehen:
Die folgende Funktion kann dabei helfen, fehlerhafte reguläre Ausdrücke in Ihren Wörterbuchschlüsseln zu finden (da die Fehlermeldung von multiple_replace nicht sehr aussagekräftig ist):
Beachten Sie, dass die Ersetzungen nicht verkettet, sondern gleichzeitig ausgeführt werden. Dies macht es effizienter, ohne die Möglichkeiten einzuschränken. Um den Effekt der Verkettung nachzuahmen, müssen Sie möglicherweise nur weitere Zeichenfolgenersatzpaare hinzufügen und die erwartete Reihenfolge der Paare sicherstellen:
quelle
Hier ist ein Beispiel, das bei langen Saiten mit vielen kleinen Ersetzungen effizienter ist.
Es geht darum, viele Verkettungen langer Zeichenfolgen zu vermeiden. Wir zerlegen die Quellzeichenfolge in Fragmente, ersetzen einige der Fragmente, während wir die Liste bilden, und verbinden dann das Ganze wieder zu einer Zeichenfolge.
quelle
Du solltest es wirklich nicht so machen, aber ich finde es einfach viel zu cool:
Nun
answer
ist das Ergebnis aller Ersetzungen der Reihe nachAuch dies ist sehr hackig und sollte nicht regelmäßig verwendet werden. Aber es ist nur schön zu wissen, dass Sie so etwas tun können, wenn Sie es jemals brauchen.
quelle
Ich hatte auch mit diesem Problem zu kämpfen. Bei vielen Substitutionen kämpfen reguläre Ausdrücke und sind ungefähr viermal langsamer als Schleifen
string.replace
(unter meinen Versuchsbedingungen).Sie sollten unbedingt versuchen, die Flashtext- Bibliothek zu verwenden ( Blog-Beitrag hier , Github hier ). In meinem Fall war es etwas mehr als zwei Größenordnungen schneller, von 1,8 s bis 0,015 s (reguläre Ausdrücke dauerten 7,7 s). für jedes Dokument.
Es ist leicht, Anwendungsbeispiele in den obigen Links zu finden, aber dies ist ein funktionierendes Beispiel:
Beachten Sie, dass Flashtext Ersetzungen in einem einzigen Durchgang vornimmt (um zu vermeiden, dass a -> b und b -> c 'a' in 'c' übersetzen). Flashtext sucht auch nach ganzen Wörtern (also stimmt 'is' nicht mit 'th is ' überein ). Es funktioniert gut, wenn Ihr Ziel aus mehreren Wörtern besteht (indem Sie "Dies ist" durch "Hallo" ersetzen).
quelle
<p>
durch/n
. Ich habe Ihren Ansatz ausprobiert, aber mit Tags scheint Flashtext ihn nicht zu analysieren?<
und>
markieren (aber beim Ersetzen enthalten sein)?Ich bin der Meinung, dass diese Frage der Vollständigkeit halber eine einzeilige Antwort auf die rekursive Lambda-Funktion benötigt, nur weil. Also da:
Verwendungszweck:
Anmerkungen:
Hinweis: Wie bei allen rekursiven Funktionen in Python führt eine zu große Rekursionstiefe (dh zu große Ersatzwörterbücher) zu einem Fehler. Siehe zB hier .
quelle
sys.getrecursionlimit()
ist ein Paar 1000, max. Verwenden Sie eine Schleife oder ähnliches oder versuchen Sie, die Ersetzungen zu vereinfachen.Ich weiß nichts über Geschwindigkeit, aber dies ist meine tägliche schnelle Lösung:
... aber ich mag die # 1 Regex Antwort oben. Hinweis - Wenn ein neuer Wert eine Teilzeichenfolge eines anderen ist, ist die Operation nicht kommutativ.
quelle
Sie können die
pandas
Bibliothek und diereplace
Funktion verwenden, die sowohl exakte Übereinstimmungen als auch Regex-Ersetzungen unterstützt. Zum Beispiel:Und der geänderte Text lautet:
Ein Beispiel finden Sie hier . Beachten Sie, dass die Ersetzungen im Text in der Reihenfolge erfolgen, in der sie in den Listen aufgeführt sind
quelle
Um nur ein Zeichen zu ersetzen, verwenden Sie das
translate
undstr.maketrans
ist meine Lieblingsmethode.tl; dr>
result_string = your_string.translate(str.maketrans(dict_mapping))
Demo
quelle
Ausgehend von der wertvollen Antwort von Andrew entwickelte ich ein Skript, das das Wörterbuch aus einer Datei lädt und alle Dateien im geöffneten Ordner ausarbeitet, um die Ersetzungen vorzunehmen. Das Skript lädt die Zuordnungen aus einer externen Datei, in der Sie das Trennzeichen festlegen können. Ich bin ein Anfänger, aber ich fand dieses Skript sehr nützlich, wenn ich mehrere Ersetzungen in mehreren Dateien vornehme. Es wurde ein Wörterbuch mit mehr als 1000 Einträgen in Sekunden geladen. Es ist nicht elegant, aber es hat bei mir funktioniert
quelle
Das ist meine Lösung für das Problem. Ich habe es in einem Chatbot verwendet, um die verschiedenen Wörter gleichzeitig zu ersetzen.
das wird werden
The cat hunts the dog
quelle
Ein weiteres Beispiel: Eingabeliste
Die gewünschte Ausgabe wäre
Code:
quelle
Oder nur für einen schnellen Hack:
quelle
Hier ist eine andere Möglichkeit, dies mit einem Wörterbuch zu tun:
quelle