51

Pythonと正規表現を使用してテキストの正規化を行っています。すべての「u」または「U」を「you」に置き換えたいと思います。これが私がこれまでにしたことです:

import re
text = 'how are u? umberella u! u. U. U@ U# u '
print re.sub (' [u|U][s,.,?,!,W,#,@ (^a-zA-Z)]', ' you ', text)

私が得る出力は次のとおりです。

how are you  you berella you  you  you  you  you  you

ご覧のとおり、問題は「umberella」が「berella」に変更されていることです。また、「u」の後に表示される文字を保持したいと思います。たとえば、「u!」「あなた!」に変更されます。誰かが私が間違っていることと正規表現を書くための最良の方法を教えてもらえますか?

4

5 に答える 5

72

まず、ソリューションが機能しないのはなぜですか。あなたは多くの概念を混同します。主に他のものとのキャラクタークラス。最初の文字クラスでは、交互|に由来するものを使用します。キャラクタークラスでは、パイプは必要ありません。必要なすべての文字(および文字範囲)をリストするだけです。

[Uu]

uまたは、大文字と小文字を区別しない修飾子を使用する場合は、単に記述してください。そこにパイプを書くと、文字クラスは実際にはサブジェクト文字列のパイプと一致します。

次に、2番目の文字クラスでは、奇妙な理由で文字を区切るためにコンマを使用します。また、一致する文字にコンマを含めるだけです。おそらく組み込みの文字クラスであると思われますsWその後、それらを脱出します!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)

あなたの好みに応じて。

この回答で何度かリンクしたチュートリアルを読んでみることをお勧めします。説明は非常に包括的であり、おそらく遅かれ早かれ再び遭遇するであろう正規表現の良いスタートを切るはずです。

于 2012-12-06T17:08:20.177 に答える
16

\b単語の最初または最後の空の文字列に一致する特殊文字を使用します。

print re.sub(r'\b[uU]\b', 'you', text)

スペースは他にも句読点がたくさんあるため、信頼できる解決策ではありません。そのため\b、単語の始まりまたは終わりを示すために抽象的な文字が考案されました。

于 2012-12-06T17:05:10.577 に答える
3

これは私のために働いた:

    import re
    text = 'how are u? umberella u! u. U. U@ U# u '
    rex = re.compile(r'\bu\b', re.IGNORECASE)
    print(rex.sub('you', text))

正規表現をプリコンパイルし、re.IGNORECASEを利用するため、正規表現の大文字と小文字を気にする必要はありません。ところで、私は傘のファンキーなスペルが大好きです!:-)

于 2018-03-23T08:43:14.167 に答える
2

以下のコードでも実現できます

import re

text = 'how are u? umberella u! u. U. U@ U# u '
print (re.sub (r'[uU] ( [^a-z] )', r' you\1 ', text))

また

print (re.sub (r'[uU] ( [\s!,.?@#] )', r' you\1 ', text))
于 2018-07-31T14:27:51.660 に答える
1

私が思いついた別の可能な解決策は次のとおりです。

re.sub(r'([uU]+(.)?\s)',' you ', text)
于 2017-11-14T14:21:13.157 に答える