HTML / XMLは、マークアップとコンテンツに分かれています。正規表現は、字句タグの解析を行う場合にのみ役立ちます。内容を推測できると思います。SAXパーサーに適しています。タグとコンテンツは、要素のネスト/クローズを追跡できるユーザー定義関数に配信できます。
タグの解析に関する限り、正規表現を使用してタグを解析し、ドキュメントからタグを取り除くことができます。
長年のテストの結果、私はブラウザがタグを正しく解析する方法と不正な方法の両方を解析する方法の秘密を発見しました。
通常の要素は次の形式で解析されます:
これらのタグのコアはこの正規表現を使用します
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
これ[^>]?
は代替の1つとして気付くでしょう。これは、不正な形式のタグからの不均衡な引用に一致します。
それはまた、正規表現に対するすべての悪の最も根源的なものでもあります。それが使用される方法は、それの貪欲で、一致しなければならない定量化されたコンテナを満足させるために衝突を引き起こします。
パッシブに使用すれば問題はありませんが、必要な属性/値のペアを挿入することによって何かを強制的に一致させ、バックトラックからの適切な保護を提供しない場合、それは制御不能の悪夢です。
これは単純な古いタグの一般的な形式です。[\w:]
タグ名を表すことに注意してください ?実際には、タグ名を表す有効な文字は、信じられないほどのUnicode文字のリストです。
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
さらに、すべてのタグを解析せずに特定のタグを検索できないこともわかります。つまり、可能ですが、(* SKIP)(* FAIL)のような動詞の組み合わせを使用する必要がありますが、それでもすべてのタグを解析する必要があります。
その理由は、タグ構文が他のタグなどの中に隠れている可能性があるためです。
したがって、すべてのタグを受動的に解析するには、以下のような正規表現が必要です。この特定のものは、非表示のコンテンツにも一致します。
新しいHTML、xml、またはその他の新しい構成要素が開発されたら、それを代替の1つとして追加するだけです。
Webページのメモ-これで
問題が発生したWebページ(またはxhtml / xml)を見たことがありません。見つけた場合はお知らせください。
パフォーマンスのメモ-簡単です。これは、私が見た中で最も速いタグパーサーです
(知っている方が速いかもしれません)。
特定のバージョンがいくつかあります。スクレーパーとしても優れて
います(ハンズオンタイプの場合)。
完全な生の正規表現
<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>
フォーマットされた外観
<
(?:
(?:
(?:
# Invisible content; end tag req'd
( # (1 start)
script
| style
| object
| embed
| applet
| noframes
| noscript
| noembed
) # (1 end)
(?:
\s+
(?>
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
)?
\s* >
)
[\S\s]*? </ \1 \s*
(?= > )
)
| (?: /? [\w:]+ \s* /? )
| (?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
| \? [\S\s]*? \?
| (?:
!
(?:
(?: DOCTYPE [\S\s]*? )
| (?: \[CDATA\[ [\S\s]*? \]\] )
| (?: -- [\S\s]*? -- )
| (?: ATTLIST [\S\s]*? )
| (?: ENTITY [\S\s]*? )
| (?: ELEMENT [\S\s]*? )
)
)
)
>