XML、特にHTMLを解析するための適切なツールに同意しますはパーサーであり、正規表現エンジンではない。ただし、他の人が指摘したように、正規表現を使用する方が速くて簡単で、データ形式がわかっている場合は作業が完了することがあります。
マイクロソフトには、実際には.NET Frameworkの正規表現のベストプラクティスのセクションがあり、特に入力ソースの検討について説明しています。。
正規表現には制限がありますが、次のことを考慮しましたか?
.NETフレームワークは、正規表現に関しては、バランスグループ定義をサポートするという点で独特です。
このため、正規表現を使用してXMLを解析できると思います。ただし、有効なXMLでなければならないことに注意してください(ブラウザーはHTMLを非常に許容し、HTML内での不正なXML構文を許可します)。これは、「バランスグループの定義」により、正規表現エンジンがPDAとして機能できるようになるためです。
上記の記事1からの引用:
.NET正規表現エンジン
上記のように、適切にバランスの取れた構造は正規表現では記述できません。ただし、.NET正規表現エンジンは、バランスのとれた構成を認識できるようにするいくつかの構成を提供します。
(?<group>)
-キャプチャした結果をグループという名前でキャプチャスタックにプッシュします。
(?<-group>)
-キャプチャスタックから、名前グループを含む最上位のキャプチャをポップします。
(?(group)yes|no)
-groupという名前のグループが存在する場合は、yes部分に一致します。それ以外の場合は、どの部分にも一致しません。
これらの構成体を使用すると、プッシュ、ポップ、空のスタック操作の単純なバージョンを基本的に許可することで、.NET正規表現で制限付きPDAをエミュレートできます。単純な操作は、インクリメント、デクリメント、およびゼロとの比較にそれぞれ相当します。これにより、.NET正規表現エンジンはコンテキストフリー言語のサブセット、特に単純なカウンターのみを必要とするものを認識することができます。これにより、従来とは異なる.NET正規表現で、適切にバランスのとれた個々の構成を認識することができます。
次の正規表現について考えてみます。
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
フラグを使用します。
- 単線
- IgnorePatternWhitespace(正規表現を縮小してすべての空白を削除する場合は不要)
- IgnoreCase(不要)
正規表現の説明(インライン)
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
A Better .NET正規表現テスターでこれを試すことができます。
私は次のサンプルソースを使用しました:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
これは一致を見つけました:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
実際には次のように出てきましたが:
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
最後に、Jeff Atwoodの記事「Parsing Html The Cthulhu Way」を本当に楽しんだ 。面白いことに、この質問への回答は現在4千票を超えています。