彼らは正規表現を使用していない場合はHTMLには仕事をどのように解析していますか?
-
18-09-2019 - |
質問
私はいくつかのHTML文字列と最初の回答/コメントから何かを解析または抽出する方法を求めて毎日が常にある質問を参照してください「あなたが怒りを感じないように、HTMLを解析するために正規表現を使用しないでください!」 (最後の部分が時々省略される)。
これは私にとってはかなり混乱して、私はいつも、一般的には、複雑な文字列を解析するための最良の方法は、正規表現を使用することであると考えました。それでは、どのHTMLパーサーは動作しますか?それが解析する正規表現を使用していません。
正規表現を使用する1つの特定の引数は、(のDOMDocumentが普遍的に利用可能なオプションではありませんJavaScriptの、など)の解析の代替が常に存在ではないということです。 jQueryのは、例えば、うまくDOMノードにHTML文字列を変換するための正規表現を使用して管理しているようだ。
これをCWするかどうかわからない、それは私が答えて、本当にディスカッションスレッドを意図するものではないことにしたい本物の質問です。
解決
通常トークナイザを使用します。ドラフト HTML5仕様では、「現実世界HTML」を処理するための大規模なアルゴリズムを持っています。
他のヒント
それでは、どのようにHTMLパーサに動作しますか?それが解析する正規表現を使用していない?の
さて、ノーます。
あなたは1、またはコンパイラのコース、または類似した何かをした場合は、計算過程の理論に戻ってあなたの脳内に達した場合は、言語や計算モデルのさまざまな種類があることを思い出してください。私はすべての詳細に入る資格がないんだけど、私はあなたと一緒に主要なポイントの数を確認することができます。
言語&(これらの目的のために)計算の最も簡単なタイプは、正規言語です。これらは、正規表現を生成し、有限オートマトンで認識することができます。基本的に、それはこれらの言語での文字列を「解析すると、」補助記憶装置の状態を使用しますが、ないことを意味します。 HTMLは確かに通常の言語ではありません。あなたが考えてみれば、タグのリストは、任意に深く入れ子にすることができます。例えば、テーブルは、テーブルを含めることができ、各テーブルには、ネストされたタグの多くを含めることができます。正規表現を使用すると、タグのペアを選ぶことができるかもしれないが、確かに何が任意にネストされていない。
定期的ではありません。古典的なシンプルな言語が正しく括弧にマッチしています。あなたがかもしれませんが試してみてください、あなたは常に動作します正規表現(または有限オートマトン)を構築することはできません。あなたは、ネストの深さを追跡するためのメモリを必要とします。
メモリのスタックを有する状態機械は、計算モデルの次の強度です。これは、プッシュダウンオートマトンと呼ばれ、それは文脈自由文法によって生成された言語を認識します。ここで、我々は正確にマッチした括弧を認識することができます - 。確かに、スタックはそれのための完全なメモリモデルである。
さて、これはHTMLには十分でしょうか?残念ながら、ありません。たぶん、超大型の慎重検証済みXMLのために、実際には、ここですべてのタグは常に完璧にラインアップ。現実世界のHTMLでは、あなたは簡単に<b><i>wow!</b></i>
のようなスニペットを見つけることができます。これは明らかに巣がないので、それを正しく解析するためには、スタックだけで十分強力ではありません。
の計算の次のレベルは、一般的な文法によって生成され、チューリングマシンによって認識される言語です。ステートマシン、メモリどこにでも変更することができる補助記憶装置を備えた - これは、一般的に効果がある最強の計算モデルであることが認められています。これは、プログラミング言語は何ができるかです。これは、HTMLが住んでいる複雑さのレベルです。
一つの文章でここにすべてを要約すると:一般的なHTMLを解析するために、あなたは本当のプログラミング言語ではなく、正規表現を必要とする
。 字句と解析:HTMLは、他の言語が解析されているのと同じ方法で解析されます。字句のステップは、意味のあるトークンに個々の文字のストリームを破壊します。構文解析ステップは、上の行動することができ、論理的にコヒーレント文書に、状態やメモリを使用して、トークンを組み立てるます。
正規表現は、パーサのひとつの形です。正直ツー良HTMLパーサは再帰下降を使用して、正規表現で表現することができるよりもはるかに複雑になりますA>、予測、および他のいくつかの技術が適切にテキストを解釈します。あなたが本当にそこに取得したい場合は、あなたがチェックアウトする可能性があるのlex&yaccのと同様のツールます。
HTMLの解析のための正規表現を使用しての禁止は、おそらくとしてより正確に記述する必要があります。「... HTMLを解析するために、のナイーブの正規表現を使用しないでください」の(あなたがたは怒りを感じないように)の "...と慎重に結果を扱います。"特定の具体的な目標のために、正規表現は完璧に十分であるかもしれないが、あなたはそれがだ場合、あなたの正規表現の限界を認識し、解析しているテキスト(例えばのソースに適切であるとして慎重にすることは非常に注意する必要がありますユーザー入力、)確かに非常に気をつけてます。
解析HTMLは、ツリー構造に線形テキストの変換です。正規表現は、一般的にツリー構造を扱うことができません。あなたは次のトークンを取得するために、各ポイントで必要な正規表現は、すべての時間を変更します。あなたはパーサで正規表現を使用できますが、構文解析の可能な各状態のための正規表現の配列全体が必要になります。
:あなたは、独自のカスタムコードを記述する必要があり、そのHTML文字文字によって、あなたは、現在のノードを停止する必要があるかどうかを判断するためのロジックの膨大な量を持っている必要がありますを反復処理そして次を開始します。
その理由は、これが有効なHTMLであるということです。
<ul>
<li>One
<li>Two
<li>Three
</ul>
しかし、これは次のとおりです。
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
あなたが「90%溶液」とOKしている場合は、:その後、文書をロードするためにXMLパーサを使用して結構です。または(あなたがして、コンテンツのマスターであれば、XMLは簡単ですが)正規表現を使用します。