2012-04-18 10 views
11

私はクロムやIEに

/^(.+)+Q$/.test("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") 

を実行し、それが完了するまでに約10秒かかります。 (Firefoxはほぼ瞬時にそれを評価することができます。)

なぜそんなに時間がかかるのでしょうか? (そして、なぜFirefoxがそれをすばやく行うことができるのでしょうか?)

(もちろん、私はこの特定の正規表現は実行しませんでしたが、URL正規表現http://daringfireball.net/2010/07/improved_regex_for_matching_urlsで同様の問題が発生しています例えば、これに煮詰める、すなわちブラウザがロックするようになります特定のURLがある)

var re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i; 
re.test("http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA") 
+11

http://www.regular-expressions.info/catastrophic.html – georg

+2

一つの理由は、それがバックトラックの多くをしている可能性があります。 Firefoxがなぜより速いのか、これは説明しません。たぶんいくつか追加の最適化があります。あなたが正規表現エンジンの内部の仕組みについての詳細を知りたい場合は、私は読むことをお勧めhttp://shop.oreilly.com/product/9780596528126.do –

+0

@thg」ヒットの回答をお願いし –

答えて

8

thg435によって示されるように、それは致命的なバックトラックのように聞こえます。これには優れた記事があります。Regular Expression Matching Can Be Simple And Fast

これはThompson NFAとして知られている効率的な手法を記述しています。しかし、これは現代の正規表現のすべての機能をサポートしているわけではありません。たとえば、逆参照はできません。しかし、記事で示唆したよう:

「たとえそうだとしても、 ほとんどの正規表現をトンプソンのNFAのシミュレーションを使用するのが妥当だろう、それは が必要なときだけ後戻りを引き出す特に巧妙な実装では、組み合わせることができ。 2つは バックリファレンスに対応するためだけにバックトラックに頼っています。

私はFirefoxはこれをやってすることができると思います。

+2

彼はコメントでそれを言ったら、彼はそれを回答として掲示すべきではありませんか? –

+2

@Martin。、私はまったく別の記事を提供しています。私は彼が答えを投稿すべきではないとは決して言わなかった。 –

+1

よく、リンクを投稿する前に回答を投稿した –

関連する問題