280個のワニまたは正規表現の爆発力

一般に、おそらく他の初心者のJavaScriptプログラマー(2年前)と同様に、私はすべてを自分の手で実装したいと考えていました。 そのため、280文字の恐ろしい、非常に高速な正規表現が発生しました。



ちょっとした歴史



約1年半前に、 yassライブラリについて学びました。これは、CSSセレクター( テストへのリンク )によってJavaScriptでDOM要素を見つけるための最速のツールでした。

そして、私はひどい興味を持っていました。 さらに高速な方法を思いつきました。 当時、私はJ. Friedlの第2版である「Regular Expressions Programmer's Library」という本を読んでいました。 そして今...それは夏でした、私はまだ学生であり、私は多くの時間を過ごしました。 仕事は沸騰し始めました...



音を立てるのは何ですか?



この記事を書くことにしたのは、CSSセレクターリクエストをほぼ完全に分析できる次の式のためです(CSS3標準の範囲を超えて、少し進んでも)。

/(?:(?:\s*[+>~,]\s*|\s+)|[^:+>~,\s\\[\]]+(?:\\.[^:+>~,\s\\[\]]*)*)|\[(?:[^\\[\]]*(?:\\.[^\\[\]]*)*|[^=]+=~?\s*(?:"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*'))\]|:[^\\:([]+(?:\\.[^\\:([]*)*(?:\((?:[^\\()]*(?:\\.[^\\()]*)*|"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*')\))?/g









友達になろう



この形式の普通の人は、上記の行の何も理解しないとすぐに言います! 私普通ではありませんが、 JavaScriptでこれ行う正規表現アナライザーがあります 。 実際、それは単純なフォームであることが判明しました。あるフィールドでは-正規表現、別のフィールドでは-検索のための行、そして3番目の-結果、いくつかのチェックボックスです。

「x」修飾子を使用して、この式を読み取り可能な形式で記述します(JavaScriptのエミュレーションを実装しました)。

(?:

(?:\s*[+>~,]\s*|\s+)

|

[^:+>~,\s\\[\]]+(?:\\.[^:+>~,\s\\[\]]*)*

)

|

\[(?:

[^\\[\]]*(?:\\.[^\\[\]]*)*

|

[^=]+=~?\s*

(?:

"[^\\"]*(?:\\.[^"\\]*)*"

|

'[^\\']*(?:\\.[^'\\]*)*'

)

)\]

|

:[^\\:([]+(?:\\.[^\\:([]*)*

(?:

\((?:

[^\\()]*(?:\\.[^\\()]*)*

|

"[^\\"]*(?:\\.[^"\\]*)*"

|

'[^\\']*(?:\\.[^'\\]*)*'

)\)

)?











理論のビット



明確にするために、 そして私は自分自身や正規表現の第一人者のために書いたわけではありませんが、この表現では「開始(通常の文字)*(特殊文字(通常の文字)*)*終わり」という形式のデザインが繰り返されていると言います。 これは、いくつかの文字の間に何かを見つけるためのほぼ普遍的な構造です。たとえば、引用符と囲まれた引用符の間のテキストの検索は、エスケープを考慮して許可されます。 より詳細な情報は、上記の本の「効果的な正規表現の構築」セクションにあります。

私たちの場合、これは引用符( "と ')、括弧と角括弧、および文字" + "、"> "、"〜 "、"、 "、" "、": "の間のテキストの検索に関するものです。



分析する



この式の構築の基本は、CSSセレクターを部分に分割する機能です。 私はこのようにそれを壊しました:



次に、これをすべて式と比較しましょう。

最初の部分は、「+」、「>」、「、」、「〜」、「\ s +」のいずれかを探し、そうでない場合は、その間のすべてを探しています。

2番目は角括弧を処理します。 テンプレート「[^ =] + =〜?\ S *」は、任意の複雑な正規表現を使用して属性セレクターで検索できるように作成されました。

3番目のものは、疑似セレクターの一致を検出し、括弧はオプションです。

バックスラッシュ( "\")を使用してすべての文字をエスケープするか、単一引用符または二重引用符で囲むと、制御文字として解釈されません。



おわりに



CSS3パーサーパーサーを記述するのがどれほど簡単かはすでに明らかだと思います。 実験に興味がある場合は、 こちらにアクセスしてください 。 ロボットの速度や正規表現の厳密さを改善することを犠牲にして誰かが声をかけてくれたら、とても感謝しています。

そしてもちろん、正規表現に関する一連の貴重な本の著者であるJ.フリーデルに感謝します。



PS:正規表現アナライザーの慎重さをおIびします。 中間ステップとして作成されました(ChromeとFFで確実に動作します)。 何かが機能しない場合は、変更イベントにコールバックがあり、チェックボックスをクリックして、または正規表現フィールドにスペースを挿入するだけで開始されます。



All Articles