まず、ソリューションが機能しないのはなぜですか。あなたは多くの概念を混同します。主に他のものとのキャラクタークラス。最初の文字クラスでは、交互|
に由来するものを使用します。キャラクタークラスでは、パイプは必要ありません。必要なすべての文字(および文字範囲)をリストするだけです。
[Uu]
u
または、大文字と小文字を区別しない修飾子を使用する場合は、単に記述してください。そこにパイプを書くと、文字クラスは実際にはサブジェクト文字列のパイプと一致します。
次に、2番目の文字クラスでは、奇妙な理由で文字を区切るためにコンマを使用します。また、一致する文字にコンマを含めるだけです。おそらく組み込みの文字クラスであると思われますs
。W
その後、それらを脱出します!s
それ以外の場合は、リテラルとリテラルに一致しW
ます。ただし、\W
そこにリストされている他のすべてのものがすでに含まれているため、\W
(角かっこなしで)単独で十分でした。また、最後の部分(^a-zA-Z)
も機能しません。これは、文字クラスに、、、およびすべての文字が^
含ま(
れるだけだからです。)
否定構文は、のような文字クラス全体に対してのみ機能します[^a-zA-Z]
。
実際に必要なのは、の前または後に文字がないことを主張することですu
。そのためのルックアラウンドを使用できます。利点は、それらが試合に含まれないため、削除されないことです。
r'(?<![a-zA-Z])[uU](?![a-zA-Z])'
生の文字列を使用したことに注意してください。エスケープシーケンスの問題を回避するために、正規表現には一般的に良い習慣です。
これらは、の前後に文字がないことを確認する否定的な見回しです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)
あなたの好みに応じて。
この回答で何度かリンクしたチュートリアルを読んでみることをお勧めします。説明は非常に包括的であり、おそらく遅かれ早かれ再び遭遇するであろう正規表現の良いスタートを切るはずです。