ちょっとした歴史
約1年半前に、 yassライブラリについて学びました。これは、CSSセレクター( テストへのリンク )によってJavaScriptでDOM要素を見つけるための最速のツールでした。
そして、私はひどい興味を持っていました。 さらに高速な方法を思いつきました。 当時、私はJ. Friedlの第2版である「Regular Expressions Programmer's Library」という本を読んでいました。 そして今...それは夏でした、私はまだ学生であり、私は多くの時間を過ごしました。 仕事は沸騰し始めました...
音を立てるのは何ですか?
この記事を書くことにしたのは、CSSセレクターリクエストをほぼ完全に分析できる次の式のためです(CSS3標準の範囲を超えて、少し進んでも)。
/(?:(?:\s*[+>~,]\s*|\s+)|[^:+>~,\s\\[\]]+(?:\\.[^:+>~,\s\\[\]]*)*)|\[(?:[^\\[\]]*(?:\\.[^\\[\]]*)*|[^=]+=~?\s*(?:"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*'))\]|:[^\\:([]+(?:\\.[^\\:([]*)*(?:\((?:[^\\()]*(?:\\.[^\\()]*)*|"[^\\"]*(?:\\.[^"\\]*)*"|'[^\\']*(?:\\.[^'\\]*)*')\))?/g
友達になろう
この形式の普通の人は、上記の行の何も理解しないとすぐに言います! 私
「x」修飾子を使用して、この式を読み取り可能な形式で記述します(JavaScriptのエミュレーションを実装しました)。
(?:
(?:\s*[+>~,]\s*|\s+)
|
[^:+>~,\s\\[\]]+(?:\\.[^:+>~,\s\\[\]]*)*
)
|
\[(?:
[^\\[\]]*(?:\\.[^\\[\]]*)*
|
[^=]+=~?\s*
(?:
"[^\\"]*(?:\\.[^"\\]*)*"
|
'[^\\']*(?:\\.[^'\\]*)*'
)
)\]
|
:[^\\:([]+(?:\\.[^\\:([]*)*
(?:
\((?:
[^\\()]*(?:\\.[^\\()]*)*
|
"[^\\"]*(?:\\.[^"\\]*)*"
|
'[^\\']*(?:\\.[^'\\]*)*'
)\)
)?
理論のビット
明確にするために、
私たちの場合、これは引用符( "と ')、括弧と角括弧、および文字" + "、"> "、"〜 "、"、 "、" "、": "の間のテキストの検索に関するものです。
分析する
この式の構築の基本は、CSSセレクターを部分に分割する機能です。 私はこのようにそれを壊しました:
- (第1世代の子、隣人、またはツリー全体、つまり、+>〜、_space_)
- 「:some_function(some_arguments)」形式の疑似セレクター
- 「[someAttr(=などの式)someValue]」形式の属性セレクター
次に、これをすべて式と比較しましょう。
最初の部分は、「+」、「>」、「、」、「〜」、「\ s +」のいずれかを探し、そうでない場合は、その間のすべてを探しています。
2番目は角括弧を処理します。 テンプレート「[^ =] + =〜?\ S *」は、任意の複雑な正規表現を使用して属性セレクターで検索できるように作成されました。
3番目のものは、疑似セレクターの一致を検出し、括弧はオプションです。
バックスラッシュ( "\")を使用してすべての文字をエスケープするか、単一引用符または二重引用符で囲むと、制御文字として解釈されません。
おわりに
CSS3パーサーパーサーを記述するのがどれほど簡単かはすでに明らかだと思います。 実験に興味がある場合は、 こちらにアクセスしてください 。 ロボットの速度や正規表現の厳密さを改善することを犠牲にして誰かが声をかけてくれたら、とても感謝しています。
そしてもちろん、正規表現に関する一連の貴重な本の著者であるJ.フリーデルに感謝します。
PS:正規表現アナライザーの慎重さをおIびします。 中間ステップとして作成されました(ChromeとFFで確実に動作します)。 何かが機能しない場合は、変更イベントにコールバックがあり、チェックボックスをクリックして、または正規表現フィールドにスペースを挿入するだけで開始されます。