純粋に理論的な意味では、正規表現でXMLを解析することは不可能です。ネストは正規表現に組み込まれる必要があるため、それらは以前の状態のメモリを持たないように定義されているため、任意のタグの正しいマッチングが妨げられ、ネストの任意の深さまで侵入できません。
ただし、最新の正規表現パーサーは、正確な定義に固執するのではなく、開発者が利用できるように構築されています。そのため、以前の状態の知識を利用した後方参照や再帰などがあります。これらを使用すると、XMLを探索、検証、または解析できる正規表現を作成するのが非常に簡単になります。
たとえば、
(?:
<!\-\-[\S\s]*?\-\->
|
<([\w\-\.]+)[^>]*?
(?:
\/>
|
>
(?:
[^<]
|
(?R)
)*
<\/\1>
)
)
これにより、次の適切に形成されたXMLタグまたはコメントが検出され、コンテンツ全体が適切に形成されている場合にのみ検出されます。 (この式はNotepad ++を使用してテストされていますが、これはBoost C ++のregexライブラリを使用しており、PCREに非常に近似しています。)
仕組みは次のとおりです。
- 最初のチャンクはコメントと一致します。ハングアップを引き起こす可能性のあるコメント化されたコードを処理できるように、これを最初にする必要があります。
- それが一致しない場合、タグの開始を探します。括弧を使用して名前をキャプチャしていることに注意してください。
- このタグは、で終了し
/>
てタグを完成させるか、で終了します。この>
場合、タグの内容を調べて続行します。
- 到達するまで解析を続けます
<
、その時点で式の先頭に再帰し、コメントまたは新しいタグのいずれかを処理できるようにします。
- テキストの最後か、
<
解析できないaに到達するまで、ループを続けます。もちろん、一致しないと、プロセスが最初からやり直されます。それ以外の場合は、<
おそらくこの反復の終了タグの始まりです。終了タグ内で後方参照を使用する<\/\1>
と、現在の反復(深さ)の開始タグと一致します。キャプチャグループは1つしかないため、この一致は簡単です。これにより、必要に応じて特定のタグのみをキャプチャするようにキャプチャグループを変更できますが、使用されるタグの名前とは無関係になります。
- この時点で、現在の再帰から次のレベルまでキックアウトするか、一致で終了します。
この例では、空白を処理したり、関連するコンテンツを識別したりするために単に否定する<
か>
、またはコメントの場合はを使用して[\S\s]
、キャリッジリターンや改行を含むすべてに一致する文字列を使用して、単一行でも関連するコンテンツを識別する問題を解決します。モードになり、に達するまで続行します
-->
。したがって、意味のある何かに到達するまで、すべてを有効なものとして扱います。
ほとんどの場合、このような正規表現は特に便利ではありません。XMLが適切に形成されていることを検証しますが、実際に行うのはそれだけであり、プロパティを考慮しません(ただし、これは簡単に追加できます)。タグ名の定義だけでなく、このような実際の問題も除外されているため、これは単純なものです。実際に使用するためにフィッティングすると、はるかに野獣になります。一般に、真のXMLパーサーははるかに優れています。これはおそらく、再帰のしくみを教えるのに最適です。
要するに、XMLパーサーを実際の作業に使用し、正規表現をいじりたい場合はこれを使用してください。