9

'(\s*)+'エラーが発生する理由がわかりません'nothing to repeat'。同時に'(\s?)+'うまくいきます。

この問題はかなり前から知られていることを発見しました (たとえば、正規表現エラー - 繰り返すものはありません) が、Python 3.3.1 でもまだ見られます。

したがって、この動作に合理的な説明があるかどうか疑問に思っています。

実際には、次のように、繰り返される単語または数字の行を一致させたいと考えています。

'foo foo foo foo'

私はこれを思いついた:

'(\w+)\s+(\1\s*)+'

2 番目のグループが原因で失敗しました。(\1\s*)+ ほとんどの場合、単語間にスペースが 1 つしかないため、うまくいき(\1\s?)+ます。実際には、このオプションも機能するはずです(\1\s{0,1000})+

更新: Python でのみ問題が発生したことを追加する必要があると思います。perlでは動作します:

`('foo foo foo foo' =~ /(\w+)\s+(\1\s*)+/) `

同等かどうかはわかりませんが、vim も機能します。

`\(\<\w\+\>\)\_s\+\(\1\_s*\)\+`

Update2: いつか現在の re を置き換えると言われている Python の正規表現の別の実装を見つけました。確認したところ、上記問題のあるケースではエラーは発生しません。このモジュールは個別にインストールする必要があります。ここまたはpypi経由でダウンロードできます

4

2 に答える 2

6

これに関してpythonが抱えている問題は、主にリンクされた投稿で提起されたnullの問題です。少なくとも 1 つのキャラクターを使用する場合は、代わりに次を使用することをお勧めします。

(\s+)+

とはいえ、何かが存在する必要があり、存在しない(\s*)+という考えで求めても、それはあまり意味がありません。一致することもあまり意味がありませんが、一致したパターンとして何も解釈しないのではなく、一致するものが見つからない場合は続行することを意味するオプションの一致であると言うことで、精神的に解決できます。+*?*

ただし、何かに関する Python の問題を本当に確認したい場合は、範囲を試してみることをお勧めします。たとえば、次の 2 つの例を使用して結論を​​導き出しました。

re.compile("(\s{1,})+")

それは結構です

re.compile("(\s{0,})+")

同じように失敗します。

少なくとも、これは Python の「バグ」ではないことを意味します。これは、概念的に同じ落とし穴に陥るすべての正規表現パターンに作用する意識的な設計上の決定です。私の推測 (いくつかの異なる環境で確認) では、(\s{0,})+null の可能性がある要素を明示的に繰り返すため、確実に失敗します。

ただし、一致がオプションであることを示すために多くの環境が使用されているようで*、python はこの選択に従いません。多くの場合、これは理にかなっていますが、時として奇妙な動作につながることがあります。Guido はここで正しい選択をしたと思います。スペースの存在に一貫性がないということは、ポンピング レンマに違反していることを意味し、パターンはもはやコンテキスト フリーではなくなるからです。

この場合、おそらくあまり問題にはなりませんが、その正規表現には解決できないあいまいさが必然的に存在することを意味します。

問題が発生したため、その問題を解決するために正規表現を使用することにしました。C'est la vie、あなたには 2 つの問題があります。

于 2013-07-10T20:34:41.693 に答える
0

Slater は問題の概要を説明していますが、考えてみれば、理論的には、最初に遭遇した空きスペースにある無限の数の空きスペースに一致することを追加したかっただけです。その式をコンパイルできる場合、それを適用すると、最初の文字が表示される前に無限ループが発生する可能性があります。したがって、これはバグではないだけでなく、良いことでもあります。

于 2013-07-10T20:42:32.103 に答える