Po pierwsze, dlaczego Twoje rozwiązanie nie działa. Wymieszać wiele pojęć. Głównie character class z innymi. W pierwszej klasie znaków używasz |
, która pochodzi od alternation. W klasach postaci nie potrzebujesz rury. Wystarczy wymienić wszystkie znaki (i zakresy znaków) ma:
[Uu]
Albo po prostu napisać u
jeśli używasz bez uwzględniania wielkości liter modyfikatora. Jeśli napiszesz tam rurę, klasa postaci będzie faktycznie dopasowywać rury w twoim temacie.
Teraz w drugiej klasie postaci używamy przecinka do oddzielania znaków z jakiegoś dziwnego powodu. Nie ma w tym nic poza przecinkami do postaci, które można dopasować. s
i W
prawdopodobnie mają być wbudowanymi klasami znaków. Więc uciec z nich! W przeciwnym razie po prostu pasują do literału s
i literalnie W
. Ale wtedy \W
zawiera już wszystko, co tam wymieniłeś, więc wystarczyłby sam (bez nawiasów kwadratowych). I ostatnia część (^a-zA-Z)
również nie działa, ponieważ po prostu będzie zawierała ^
, (
, )
i wszystkie litery do klasy postaci. Składnia negacji działa tylko dla całych klas znaków, takich jak [^a-zA-Z]
.
To, czego naprawdę chcesz, to stwierdzenie, że nie ma litery przed lub po u
. Możesz użyć do tego lookarounds. Zaletą jest to, że nie zostaną one uwzględnione w meczu, a tym samym nie zostaną usunięte:
r'(?<![a-zA-Z])[uU](?![a-zA-Z])'
Zauważ, że użyłem surowy ciąg. Zwykle jest to dobra praktyka dla wyrażeń regularnych, aby uniknąć problemów z sekwencjami ucieczkowymi.
To są negatywne spojrzenia, które sprawiają, że nie ma litery przed ani po u
. Jest to ważna różnica w stwierdzeniu, że w pobliżu jest znak inny niż litera (podobny do tego, co zrobiłeś), ponieważ to drugie podejście nie będzie działać na początku ani na końcu ciągu znaków.
Oczywiście można usunąć spacje wokół numeru you
z ciągu zastępczego.
Jeśli nie chcesz zastąpić u
że są obok cyfr, można łatwo zawierać cyfry do klas postaci:
r'(?<![a-zA-Z0-9])[uU](?![a-zA-Z0-9])'
a jeśli z jakiegoś powodu sąsiednia podkreślenia również dyskwalifikacji swoją u
do wymiany możesz również dołączyć. Ale wtedy klasa znaków pokrywa się z wbudowanego \w
:
r'(?<!\w)[uU](?!\w)'
Który jest w tym przypadku równoznaczne EarlGray na r'\b[uU]\b'
.
Jak wspomniano powyżej, można skrócić wszystkie z nich, używając modyfikatora niewrażliwego na wielkość liter. Biorąc pierwszy wyraz jako przykład:
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.I)
lub
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.IGNORECASE)
w zależności od preferencji.
Proponuję przeczytać kilka razy w tutorialu, który kilka razy łączyłem w tej odpowiedzi. Wyjaśnienia są bardzo obszerne i powinny dać ci dobry początek w wyrażeniach regularnych, które prawdopodobnie wcześniej czy później napotkasz.
Twoja odpowiedź była znakomita. Dzięki! – user823743
to jest interesująca ogólna technika, ale wolałbym użyć \ b, aby dopasować słowo break –
@Sam Chciałem tylko upewnić się, że implikacje użycia '\ b' były jasne (w szczególności, że cyfry i podkreślenia są w cenie). –