Wie kann ich mehrere Substitutionen mit Regex in Python machen?

Ich kann diesen Code unten verwenden, um eine neue Datei mit der Substitution von a mit aa mit regulären Ausdrücken zu erstellen.

 import re with open("notes.txt") as text: new_text = re.sub("a", "aa", text.read()) with open("notes2.txt", "w") as result: result.write(new_text) 

Ich habe mich gefragt, ich muss diese Zeile verwenden, new_text = re.sub("a", "aa", text.read()) , mehrere Male aber ersetzen Sie die Zeichenfolge für andere Buchstaben, die ich ändern möchte, um zu ändern Mehr als ein Brief in meinem Text?

Das heißt, so a -> aa , b -> bb und c -> cc .

Also muss ich diese Zeile für alle Briefe schreiben, die ich ändern möchte oder gibt es einen einfacheren Weg. Vielleicht ein "Wörterbuch" von Übersetzungen zu erstellen. Soll ich diese Briefe in ein Array stellen? Ich bin mir nicht sicher, wie ich sie anrufen soll, wenn ich es tue.

3 Solutions collect form web for “Wie kann ich mehrere Substitutionen mit Regex in Python machen?”

Die von @nhahtdh vorgeschlagene Antwort ist gültig, aber ich würde weniger pythonisch argumentieren als das kanonische Beispiel, das Code weniger opak als seine Regexmanipulationen nutzt und die eingebauten Datenstrukturen und die anonyme Funktionsfunktion von Python nutzt.

Ein Wörterbuch der Übersetzungen macht in diesem Zusammenhang Sinn. In der Tat, das ist, wie das Python-Kochbuch es tut, wie in diesem Beispiel gezeigt (kopiert von ActiveState http://code.activestate.com/recipes/81330-single-pass-multiple-replace/ )

 import re def multiple_replace(dict, text): # Create a regular expression from the dictionary keys regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys()))) # For each match, look-up corresponding value in dictionary return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) if __name__ == "__main__": text = "Larry Wall is the creator of Perl" dict = { "Larry Wall" : "Guido van Rossum", "creator" : "Benevolent Dictator for Life", "Perl" : "Python", } print multiple_replace(dict, text) 

Also in deinem Fall kannst du einen dict trans = {"a": "aa", "b": "bb"} und dann übergeben sie in multiple_replace zusammen mit dem Text, den Sie übersetzen möchten. Grundsätzlich ist alles, was Funktion tut, ist die Schaffung eines riesigen Regex mit all Ihren Regexen zu übersetzen, dann, wenn man gefunden wird, übergeben eine Lambda-Funktion zu regex.sub , um die Übersetzung Wörterbuch suchen.

Sie können diese Funktion beim Lesen aus Ihrer Datei verwenden, zum Beispiel:

 with open("notes.txt") as text: new_text = multiple_replace(replacements, text.read()) with open("notes2.txt", "w") as result: result.write(new_text) 

Ich habe diese genaue Methode in der Produktion tatsächlich verwendet, in einem Fall, in dem ich die Monate des Jahres von Tschechisch in Englisch für eine Web-Scraping-Aufgabe übersetzen musste.

Wie @nhahtdh darauf hingewiesen, ein Nachteil zu diesem Ansatz ist, dass es nicht präfix-frei: Wörterbuch-Schlüssel, die Präfixe von anderen Wörterbuch-Schlüssel wird dazu führen, dass die Methode zu brechen.

Sie können Capturing-Gruppe und Backreference verwenden:

 re.sub(r"([characters])", r"\1\1", text.read()) 

Setzen Sie Zeichen, die Sie verdoppeln möchten zwischen [] . Für den Fall der Kleinbuchstaben a , b , c :

 re.sub(r"([abc])", r"\1\1", text.read()) 

In der Ersatzzeichenfolge können Sie sich auf alles beziehen, was von einer Erfassungsgruppe () mit \n Notation übereinstimmt, wobei n eine positive ganze Zahl (0 ausgeschlossen) ist. \1 bezieht sich auf die erste Erfassungsgruppe. Es gibt eine andere Notation \g<n> wobei n eine nicht-negative ganze Zahl sein kann (0 erlaubt); \g<0> bezieht sich auf den ganzen Text, der mit dem Ausdruck übereinstimmt.


Wenn Sie alle Zeichen außer der neuen Zeile verdoppeln möchten:

 re.sub(r"(.)", r"\1\1", text.read()) 

Wenn Sie alle Zeichen verdoppeln möchten (neue Zeile enthalten):

 re.sub(r"(.)", r"\1\1", text.read(), 0, re.S) 

Mit Tipps von, wie man eine "stringy" Klasse macht , können wir ein Objekt identisch mit einem String aber für eine zusätzliche sub Methode:

 import re class Substitutable(str): def __new__(cls, *args, **kwargs): newobj = str.__new__(cls, *args, **kwargs) newobj.sub = lambda fro,to: Substitutable(re.sub(fro, to, newobj)) return newobj 

Dies erlaubt es, das Buildermuster zu verwenden, das schöner aussieht, aber nur für eine vorgegebene Anzahl von Substitutionen arbeitet. Wenn du es in einer Schleife benutzt, gibt es keinen Punkt, der eine zusätzliche Klasse mehr schafft. Z.B

 >>> h = Substitutable('horse') >>> h 'horse' >>> h.sub('h', 'f') 'forse' >>> h.sub('h', 'f').sub('f','h') 'horse' 
  • Zählerscheinen von mehreren Teilstrings in einer Zelle Pandas
  • Wie vergleiche ich zwei Strings in Python?
  • Python 3.2 Ersetzen Sie alle Wörter in einem Textdokument, das eine bestimmte Länge ist?
  • Abrufen eines Datums aus einer komplexen Zeichenfolge in Python
  • Überprüfen Sie die Python-Funktion, um das Isogramm aus Codewars zu bestimmen
  • Wie füge ich die Anzahl der Artikelfrequenzen in einer Liste in Python 3.2 an?
  • Python-String-Verarbeitungsoptimierung
  • Wie finde ich den ersten Index eines Satzes von Zeichen in einer Zeichenfolge
  • Openpyxl - wandelnder Zellenwert von 'utf-8' zu '' ascii '
  • Str Performance in Python
  • RPython Kopie String mit Zitaten von R bis Python
  • Python ist die beste Programmiersprache der Welt.