たとえば、この電子メールの正規表現検証: ^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$
をご覧ください。注意深く見ると3つの部分があります:品物、@
文字、その他のものです。正規表現では電子メールアドレスに@
が必要なので、文字列aaaaaaaaaaaaaaaaaaaaaa!
は一致しません。正規表現エンジンでは、必要な文字がすべて文字列内にあることを確認しないのはなぜですか?
しかし、ほとんどの正規表現engineは、この組み合わせで突発的にバックトラックします。 (PCRE、Regex101のパワーは、ほとんどのものよりもスマートですが、他の正規表現や文字列の組み合わせは壊滅的なバックトラッキングを引き起こす可能性があります)。
Big Oについて多くのことを知る必要はなく、コンビナトリアルは指数関数。だから正規表現エンジンは、文字列に必要な文字が含まれていることを確認しないでください(なぜなら、早期に終了することができるからです)。
残念なことに、私が大惨事のバックトラックについて読んだことの大部分は、正規表現エンジン/コンパイラがより良くする必要がある可能性を探る代わりに、悪い正規表現を書く正規表現ライターに責任を課します。正規表現のエンジン/コンパイラを見ているものがいくつか見つかりましたが、あまりにも技術的です。より多くの経験を得た後、バック来る
は、私は正規表現は、コンピュータではなく、プログラマによって決定された実行計画を意味し、declarativeであることを知っています。最適化は、正規表現エンジンが最も異なる方法の1つです。
PCREとPerlは、バックトラック制御動詞の導入によって宣言的な現状に挑戦してきましたが、動詞のない他のエンジンであり、大惨事を繰り返している可能性があります。
'lazy'数量詞' 'と' '*戦場に出た:それは間違っているツールです。それは、マッチングを効率的にするために賢明に使用するのは作者にあります。デフォルトでは、正規表現は** 'greedy' **であり、すべての組み合わせをチェックします。 –
我々は学術的な関心率を取る場合、これは持っていることがあります。たぶん、代わりの全体の正規表現エンジンは(書き換えられることを要求し、1ではなく、特定のケースから、想定しそのせいワット複雑な問題に簡単に()一般解(| SH)ウルド?存在するのはむしろ大胆であるかもしれません)、プログラマは既にこのような問題について知っていますが、ここではスマートなものでなければなりません。最初に '@'自身のstrpos/indexのチェックをしてください。 (あなたも試してみて、電子メールアドレスを確認する正規表現「解決策」を考え出すを試みるべきではありません、我々はあまりにも、彼らはすでに、すでに知っていると仮定し¹;) – CBroe
@CBroeははい、私はうまく(電子メールの検証のための正規表現を使用しないように知っています私はおそらくこれではなく、警告するだろうが、失敗を通るだろうが)、実際の例を使いたいと思った。 '...今、私たちはどのくらいの時間をしたいと思う(... | B | | CDE)や、'など、より複雑な状況、 - – Laurel