Ответ 1
Во-первых, почему ваше решение не работает. Вы смешиваете множество концепций. В основном класс символов с другими. В первом классе символов вы используете |
, который вытекает из alternation. В классах персонажей вам не нужен труба. Просто перечислите все символы (и диапазоны символов), которые вы хотите:
[Uu]
Или просто напишите u
, если вы используете нечувствительный к регистру модификатор. Если вы пишете там трубу, класс символов будет фактически соответствовать трубам в вашей теме.
Теперь во втором классе символов вы используете запятую для разделения ваших символов по какой-то нечетной причине. Это также не включает в себя запятые для сопоставимых символов. s
и W
, вероятно, должны быть встроенными классами символов. Тогда убегите от них! В противном случае они будут просто соответствовать буквальному s
и буквальному W
. Но тогда \W
уже включает все остальное, что вы там указали, поэтому было бы достаточно \W
(без квадратных скобок). И последняя часть (^a-zA-Z)
также не работает, потому что она будет просто включать ^
, (
, )
и все буквы в класс символов. Синтаксис отрицания работает только для целых классов символов, таких как [^a-zA-Z]
.
То, что вы на самом деле хотите, это утверждать, что перед вами или после вашего u
нет буквы. Вы можете использовать образы для этого. Преимущество состоит в том, что они не будут включены в совпадение и, следовательно, не будут удалены:
r'(?<![a-zA-Z])[uU](?![a-zA-Z])'
Обратите внимание, что я использовал необработанную строку. Обычно является хорошей практикой для регулярных выражений, чтобы избежать проблем с escape-последовательностями.
Это негативные образы, которые гарантируют, что символ буквы не будет до или после вашего u
. Это важная разница в утверждении, что вокруг есть небуквенный характер (что похоже на то, что вы сделали), потому что последний подход не будет работать в начале или конце строки.
Конечно, вы можете удалить пробелы вокруг you
из строки замены.
Если вы не хотите заменять u
, которые находятся рядом с цифрами, вы можете легко включить цифры в классы символов:
r'(?<![a-zA-Z0-9])[uU](?![a-zA-Z0-9])'
И если по какой-то причине смежное подчеркивание также дисквалифицирует ваш u
для замены, вы также можете включить это. Но тогда класс символов совпадает со встроенным \W
:
r'(?<!\w)[uU](?!\w)'
Что в данном случае эквивалентно EarlGray r'\b[uU]\b'
.
Как упоминалось выше, вы можете сократить все это, используя модификатор без учета регистра. В качестве примера возьмем первое выражение:
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.I)
или
re.sub(r'(?<![a-z])u(?![a-z])', 'you', text, flags=re.IGNORECASE)
в зависимости от ваших предпочтений.
Я предлагаю, чтобы вы немного читали учебник, который я связывал несколько раз в этом ответе. Объяснения очень полные и должны дать вам хороший головной убор на регулярных выражениях, которые вы, вероятно, встретите снова рано или поздно.