2016-07-19 14 views
0

句読点と記号を別のトークンとして分割するように、メインテキストから区切りたいと思います。私は次の記号%&()+,-./:;=–‘’“”″を含むテキストファイルを持っていて、それぞれの記号を\ssymbol\s\sはスペースを意味します)に置き換えたいと思います。 ..がお互いに隣接している場合は、\s..\sに置き換えます。私はテキストを印刷するとき部分文字列をスペース+部分文字列+スペースで置換するregex Python3.xを使用

>>> punc = "[%&\(\)\+,-./:;=–‘’“”″]+" 
>>> import re 
>>> pattern = re.compile(punc) 
>>> text = "hi. hi.. hi; hi;; 55% good& good&&" 
>>> text = re.sub(pattern, ' '+str(pattern)+' ', text) 

が、私は以下の取得:これは私がこれまで試してみました何である

>>> print(text) 
hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> hi <_sre.SRE_Pattern object at 0x00000000035E14E0> 55 <_sre.SRE_Pattern object at 0x00000000035E14E0> x <_sre.SRE_Pattern object at 0x00000000035E14E0> 

しかし、私は、出力は次のようになりたい:

hi . hi .. hi ; hi ;; 55 % good & good && 

いくつかの試行の後、私は正しい正規表現をコンパイルできないことに気付きました。あなたの親切な助けが大変ありがとう!

答えて

1

あなたがしようとしていることに対処する適切な方法は、キャプチャグループを使用することです。これにより、あなたの試合を参照することができます。最初に、私があなたの試みがあなたに見せた結果を与える理由を説明することから始めましょう。

あなたがre.sub機能で

を見たものを見たのはなぜstr(pattern)パターンオブジェクトの文字列表現を返しますので、あなたは第三引数として' '+str(pattern)+' 'それを与えるとき、これは、文字列" <_sre.SRE_Pattern object at some_memory_location> "に評価されます、 パターンではありません。

さて、Python 3.4と3.5では、str(pattern)が私のためにre.compile('[%&\\(\\)\\+,-./:;=–‘’“”″]')を返します。どのバージョンのPythonを使用していますか?おそらくPython 2のバージョンですか?

ソリューション

私は前に触れたように、あなたのソリューションは、groupsをキャプチャ利用が必要です。グループを表すには、単にカッコを使用します。あなたが一つのグループだけ必要なので、あなたのケースでは、溶液は十分に簡単です:リテラル文字列を私のために

>>> import re 
>>> pattern = re.compile(r"([%&\(\)\+,-./:;=–‘’“”″]+)") 

お知らせを、私は、文字列の開始前にrを使用しました。これは生の文字列を表し、文字列はPythonで定義されているエスケープシーケンスを無視します。エスケープシーケンスは、例えば、'\t'のようなもので、タブを表します。ただし、r'\t'を使用すると、実際の文字列は\tになります。

>>> text = "hi. hi.. hi; hi;; 55% good& good&&" 
>>> pattern.sub(r' \1 ', text) 
'hi . hi .. hi ; hi ;; 55 % good & good && ' 

通知は、私は単にモジュールレベルの関数re.subではなく、パターンオブジェクトのsub方法を用います。大したことではありませんが、それはちょうど私にとってはきれいです。また、置換引数については、r' \1 'を使用しました。この\1は、あなたのパターンでキャプチャされたの最初のグループを指します。複数のグループがある場合は、たとえばパターンを逆にしたい場合は\2 \1のようなものを使用できます。もう一度、エスケープシーケンスです!

潜在的な改善

あなたが2つ以上の文字などに対処したいどのようにあなたの仕様では不明でした3文字。だからあなたのパターンは以下のようなものをそのような状況に対処します:

>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello," 
>>> pattern.sub(r' \1 ', text2) 
'hi . hi .. hi ; hi ;; 55 % good & good && hi &&& hello , ' 

多分それはあなたが何ですが、多分あなたは、2個の異なる一致として「& & &」を考えたい:「& &」と「&」。あなたは量指定子を使用して、その状況に対処することができます

>>> pattern2 = re.compile(r'([%&\(\)\+,-./:;=–‘’“”″]{1,2})') 
>>> pattern2.sub(r' \1 ', text2) 
'hi . hi .. hi ; hi ;; 55 % good & good && hi && & hello , ' 

代わりの一または-以上を表し+記号を使用して、あなたは、よりきめ細かい制御を持つようにブラケット表記を使用することができます。たとえば、{1,3}は1〜3に一致します。{3}は正確に3に一致します。{3、}は3以上に一致します。

+0

ご協力いただきありがとうございます。あなたが適切に説明したように私の問題を解決するのはとても簡単だとは思わなかった。 Pythonのバージョンに関しては、3.3.2で実装しようとしていました。私は今3.4をインストールします。改善セクションに関しては、1つ以上の文字に対応したいと思います。同じタイプの3文字も1つのマッチとして扱う必要があります。これがあなたが実演したものです。ご協力いただきありがとうございます。 – Mohammed

+0

しかし、 '.sub(r '\ l'、...)'の使い方を理解したいと思います。 – Mohammed

+0

@モハメッドああ!はい、あなたのパターンで取り込まれた最初のグループを指しています!グループが複数ある場合は、3番目のグループを「3番目のグループ:\ 3」と呼ぶことができます。私の編集を参照してください。 –

関連する問題