Erstens, warum funktioniert Ihre Lösung nicht? Sie vermischen viele Konzepte. Meistens character class mit anderen. In der ersten Zeichenklasse verwenden Sie |
, die von alternation stammt. In Zeichenklassen brauchen Sie die Pipe nicht. Listen Sie einfach alle Zeichen (und Zeichenbereiche) Sie wollen:
[Uu]
Oder einfach schreiben u
, wenn Sie die Groß- und Kleinschreibung Modifikator. Wenn Sie dort eine Pipe schreiben, wird die Zeichenklasse tatsächlich den Pipes in Ihrer Betreff-Zeichenfolge entsprechen.
Jetzt in der zweiten Zeichenklasse verwenden Sie das Komma, um Ihre Zeichen aus irgendeinem seltsamen Grund zu trennen. Dazu gehören auch Kommas in die matchbaren Zeichen. s
und W
sind wahrscheinlich die eingebauten Zeichenklassen. Dann entkomme ihnen! Andernfalls werden sie nur literal s
und Literal W
übereinstimmen. Aber dann \W
enthält bereits alles, was Sie dort aufgeführt, so eine \W
allein (ohne eckige Klammern) wäre genug gewesen. Und der letzte Teil (^a-zA-Z)
funktioniert auch nicht, weil es einfach ^
, (
, )
und alle Buchstaben in die Zeichenklasse enthält. Die Negationssyntax funktioniert nur für ganze Zeichenklassen wie [^a-zA-Z]
.
Was Sie eigentlich wollen, ist zu behaupten, dass es keinen Brief vor oder nach Ihrer u
gibt. Sie können dafür lookarounds verwenden. Der Vorteil besteht darin, dass sie nicht in das Spiel einbezogen werden und somit nicht entfernt werden:
r'(?<![a-zA-Z])[uU](?![a-zA-Z])'
Bitte beachte, dass ich eine rohe Zeichenfolge verwendet. Ist in der Regel eine gute Übung für reguläre Ausdrücke, um Probleme mit Escape-Sequenzen zu vermeiden.
Dies sind negative Lookarounds, die sicherstellen, dass vor oder nach Ihrem u
kein Buchstabe vorhanden ist. Dies ist ein wichtiger Unterschied zu der Behauptung, dass es ein Nicht-Buchstaben-Zeichen gibt (das ähnlich zu dem ist, was Sie getan haben), weil der letztere Ansatz nicht am Anfang oder Ende der Zeichenkette funktioniert.
Natürlich können Sie die Leerzeichen um you
aus der Ersatzzeichenfolge entfernen.
Wenn Sie nicht u
ersetzen mögen, die Ziffern nächsten sind, können Sie einfach die Ziffern in die Zeichenklassen sind:
r'(?<![a-zA-Z0-9])[uU](?![a-zA-Z0-9])'
Und wenn aus irgendeinem Grunde ein benachbarter Strich würde auch disqualifizieren Ihre u
für den Ersatz könnten Sie das ebenfalls einschließen. Aber dann fällt die Zeichenklasse mit dem eingebauten in \w
:
r'(?<!\w)[uU](?!\w)'
Welche ist, in diesem Fall entspricht EarlGray des r'\b[uU]\b'
.
Wie oben erwähnt, können Sie alle verkürzen, indem Sie den Modifikator ohne Berücksichtigung der Groß- und Kleinschreibung verwenden. Unter dem ersten Ausdruck als Beispiel:
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.I)
oder
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.IGNORECASE)
je nach Ihren Wünschen.
Ich schlage vor, dass Sie das Tutorial lesen, das ich in dieser Antwort mehrmals verlinkt habe. Die Erklärungen sind sehr umfassend und sollten Ihnen einen guten Einstieg in die regulären Ausdrücke geben, denen Sie wahrscheinlich früher oder später wieder begegnen werden.
Ihre Antwort war hervorragend. Vielen Dank! – user823743
Dies ist eine interessante allgemeine Technik, aber ich würde lieber \ b verwenden, um einen Wortbruch zu entsprechen –
@Sam Ich wollte nur sicherstellen, dass die Auswirkungen der Verwendung von '\ b' klar waren (insbesondere, dass Ziffern und Unterstriche sind im Lieferumfang enthalten). –