2012-12-06 4 views
27

私はPythonと正規表現を使用してテキスト正規化を行っています。私はすべての「U」または「U」を「あなた」と置き換えたいと思います。ここ は、私がこれまで行っているものです:私が得るPython re.sub():すべての 'u'または 'U'を 'you'に置き換える方法

import re 
text = 'how are u? umberella u! u. U. [email protected] 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!' 「あなた!」に変更されます。誰かが私が間違っていることを教えてもらえますか、正規表現を書くための最良の方法は何ですか?

答えて

48

まず、ソリューションが機能しないのはなぜですか。多くのコンセプトが混在しています。ほとんどcharacter classと他のもの。最初の文字クラスでは、alternationに由来する|を使用します。文字クラスでは、パイプは必要ありません。

[Uu] 

それとも単にあなたは、大文字と小文字を区別しない修飾子を使用する場合uを書く:ちょうどすべての文字(および文字範囲)希望を一覧表示します。そこにパイプを書くと、文字クラスは実際には対象文字列のパイプと一致します。

2番目の文字クラスでは、奇妙な理由で文字を区切るためにコンマを使います。一致する文字にカンマを含めるだけで何もできません。 sWはおそらく組み込みの文字クラスであるはずです。その後、それらをエスケープ!それ以外の場合は、リテラルsとリテラルWとが一致します。しかし、\Wにはすでにそこにリストされているものがすべて含まれているため、\W(大括弧なし)だけで十分でした。最後の部分は(^a-zA-Z)でも機能しません。^()、およびすべての文字を文字クラスに含めるだけです。否定構文は、[^a-zA-Z]のような文字クラス全体に対してのみ機能します。

あなたが実際に望むのは、あなたのuの前または後ろに手紙がないことを主張することです。あなたはそれにlookaroundsを使うことができます。メリットには含まれず、削除されないという利点があります。

r'(?<![a-zA-Z])[uU](?![a-zA-Z])' 

私は生の文字列を使用しています。エスケープシーケンスの問題を避けるために、一般的に正規表現の良い習慣です。

これらは、あなたのuの前後に文字がないことを確認するネガティブな解決方法です。後者の方法は文字列の最初または最後では機能しないため、これは文字以外の文字があることを主張する重要な違いです(これはあなたのやり方に似ています)。

もちろん、youのスペースを置換文字列から削除できます。

あなたは数字の隣にあるuを交換したくない場合は、あなたが簡単に文字クラスの中に数字を含めることができます。

r'(?<![a-zA-Z0-9])[uU](?![a-zA-Z0-9])' 

そして、いくつかの理由で、隣接するアンダースコアはまたあなたのuを失格となる場合交換のために、それも含めることができます。しかし、その後の文字クラスは、組み込みの\wと一致:

、この場合には、EarlGrayの r'\b[uU]\b'と同等です
r'(?<!\w)[uU](?!\w)' 

上記のように、大文字と小文字を区別しない修飾子を使用すると、これらをすべて短縮できます。あなたの好みに応じて

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) 

:例として、最初の式を取ります。

私はあなたがこの答えで何度もリンクしたチュートリアルを通していくつかの読書をすることをお勧めします。説明は非常に包括的で、正規表現に関する良いスタートアップを提供するはずです。

+2

答えは未解決です。ありがとう! – user823743

+0

これは興味深い一般的なテクニックですが、単語区切りと一致させるために\ bを使用したいと思います。 –

+2

@Sam私は '\ b'を使用することの意味が明確であることを確認したかっただけです(特に数字とアンダースコアは含まれています)。 –

11

先頭または単語の最後に空の文字列にマッチする特殊文字\b、使用します。他の句読点の多くもあるので、信頼性の高いソリューションではありませんので、

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

スペースを抽象的な文字\bは、単語の開始または終了を示すために考案されたものです。

+2

'\のx08''は '\ b''は'と同じである' ことを除いて。あなたはエスケープする必要があります( ''\\ b''または' r'\ b'')! – mata

+1

これは、コードに定義されているように、「テキスト」のコードの出力です。 どのようですか? umberella u! u。 U. U @ U#u あなたには何も変更されていません。 – user823743

+1

@ user823743はい、私は正規表現の前に 'r'を忘れています。これはWoobleによって編集されたものです(ありがとう!)。 –

0

私がいた思い付いたもう1つの可能な解決策:

re.sub(r'([uU]+(.)?\s)',' you ', text) 
関連する問題