2011-10-23 5 views
1

私は正規表現を学習しています。私はPythonが使用しているメカニズムをチェックしたいと思います。Python 2.6の正規表現メカニズム?

s = re.findall(ur"\d+\.?\d+", "123,45.567 78"). 

まず、私は結果があることを行っのみ45.567

私はそれを実行すると、Iまし小数を含むすべての数字([ "123" されたことを考えた:

私は正規表現を持っています、 "45.567"、 "78"])、使用されるプロセスはあまり明確ではありません。

ここに私の理解があります: Pythonは最初に、\ d +という式で始まります。これは123でOKです(カンマの前に可能な限り貪欲な検索があります)。次に、オプションのドット(。?)が存在しないことを期待しています。これは大丈夫です。次に、1つ以上の数字が必要です。しかし、次の文字はカンマ(、)で、受け入れられません。 Pythonは12に戻ります(ドロップ3)。 12フルフィル最初の\ d +。次に、そこには存在しない1つ以上の数字と3つの数字が必要となるオプションのドットが必要です。つまり、123 fullfils正規表現全体です。

Pythonは123のオフセット2を記憶し、123の後ろにもう一度開始します。つまり、Pythonは正規表現全体を文字列45.567,78で使用し始めますか?

つまり、正規表現全体が3回使われます。初めてそれは123 それは45.567見つけて.はオプションであるため、第三の時間が、それは(それがすべて一致した理由多分あなたは今参照)78.

+1

質問の書式設定にもっと注意を払ってください。テキストの大きなブロックは読みにくい。コードの書式設定を使用します。 – Mat

+0

's = re.findall(ur" \ d + \?\ d + "、" 123,45,567 78 "、re.DEBUG)'を実行すると、Pythonの動作に従うのに役立ちます。 – robert

+0

最初の '123'がどのようにマッチしているかについてのあなたの記述は正しいです。これがマッチした後、正規表現エンジンは最初のマッチの直後の位置(カンマの直前の位置)でマッチしようとしますが、これは失敗します。しかし、エンジンはあきらめることはありません。文字列の次の文字に "_に沿って"衝突し、 '45.567'にマッチすることができます。その後、スペースの直前でもう一度失敗してバンプすると、3番目のマッチが見つかります。正規表現エンジンは、文字列内の最後の文字の後の位置であっても、文字列内のすべての位置で一致するかどうかを確認するために衝突します。 – ridgerunner

答えて

4

\d+\.?\d+は常にも\d+\d+にマッチします見つける秒の時間を見つけます。したがって、制約が許す限り、それをバックトラックすることができます。

1

documentation of findall(強調鉱山)から:

戻り文字列のパターンが全て非オーバーラップマッチ、文字列のリストとして。

これはあなたが見ている動作を表しているようです。オーバーラップしないマッチを取得するには、前のマッチの終了後に次のマッチを開始する必要があります。