2013-09-24 10 views
6

における数量詞として使用される場合今日、私は次の正規表現に出くわしたとRubyがそれでどうなるのか知りたいと思った:意味は、後者は、正規表現

> "#a" =~ /^[\W].*+$/ 
=> 0 
> "1a" =~ /^[\W].*+$/ 
=> nil 

この場合、Rubyは+文字を無視しているようです。それが間違っている場合、私はそれが何をしているのか分かりません。私は*がエスケープされておらず、量子として使用されているので、それが量子として解釈されていないと推測しています。 Perl/Rubyの正規表現では、特殊文字として解釈できない文脈で文字(例:-)が使用されるときに、リテラルとして扱われます。しかし、この場合は、lvalue文字列に+が存在しないため、最初の一致が失敗することが予想されます。

これは+文字を微妙に正しく使用していますか?上記の動作はバグですか?私は明白な何かを欠いていますか

+0

どこにこの正規表現がありますか? –

+0

私の仕事の中で遭遇した第三者のセキュリティコンテンツ。私は正規表現は作者が意図したものではないと思っていますが、Rubyの動作を見たとき、私はこの仮定について疑問を持ち始めました。 –

答えて

5

*の後には、確かに+を使用できます。あなたはそれについて少し読むことができますon this site*の後の+は、所有量限定子と呼ばれます。

それは何ですか? *のバックトラッキングを防止します。

あなたは.*cabcdeに一致するように、これを使用してのようなものを持っている場合通常、.*は、まず文字列全体(abcde)と一致し、正規表現が.*cと一致しないことができるので、エンジンはAに戻って1つの文字を移動します一致するものがあるかどうかを確認する時間です(これがバックトラッキングです)。

cに戻ったらabcabcdeになります。今

、エンジンはバックトラックする文字の何百万、数百文字をバックトラックする、とあなたはグループや複数の*(または+または{m,n}フォーム)を入れ子にしている場合、あなたはすぐに数千人で終わることができていることを想像し、 catastrophic backtrackingと呼ばれます。

これは、所有量の定量化が便利な場所です。実際には、どんな形式のバックトラッキングも防止します。上記の正規表現では、abcde.*+cと一致しません。 .*+が文字列全体を消費すると、それは戻ってきません。文字列の最後にcがないので、一致は失敗します。

したがって、所有量限定子の別の可能な使用法は、エンジンがそれをサポートできるならば、いくつかの正規表現の性能を向上させることができるということです。

あなたの正規表現/^[\W].*+$/については、私は、所有量限定子が提供する改善はないと思います。最後に、簡単には/^\W.*+$/と書き直すことができます。

+0

あなたが得る唯一の改善点は、エンジンが中間の状態を保存する必要がないことです。これは、 '。*'(後でバックトラックするために使用されます)と一致することになります。しかし、パターンはとにかく戻ってこないので、その分節約はありません。 –

+0

素晴らしい書き込み - ありがとうございます。 –

+0

@EricWalkerあなたは大歓迎です:) – Jerry

関連する問題