|
■htmlをなかなか個人のパーサーで取り扱うってのは難しいところまで来ています。
なので、一般的には、HtmlAgilityPackなりNokogiriなりのパーサーを利用しますが、
それでも、とにかくライブラリといった話ではなく、
「考え方として、とっかかりとして」知りたい、
といういうことであれば、根本の所の流れだけ記載します。
下記のような考え方が正規表現でやろうが、ライブラリを使おうが共通です。
@「対象は全体である」からスタート
<blockquote>aaa<div>bbb<a ....>ccc</a>りんご<a ....>deeeee</a><b>bb</b></div
><blockquote>
A操作タグは, div, blockquote, a である。divの最小マッチで走査開始
<div>(bbb<a ....>ccc</a>afdfs<a ....>deeeee</a><b>bb</b>)</div>
divの最小マッチは以上のように見つかった。次の走査は( )内の文字列とする
対象の文字列は
bbb<a ....>ccc</a>りんご<a ....>deeeee</a><b>bb</b>である。
B操作タグは, div, blockquote, a である。divの最小マッチで走査開始
divは見つからない
C操作タグは, div, blockquote, a である。blockquoteの最小マッチで走査開始
blockquoteは見つからない
D操作タグは, div, blockquote, a である。blockquoteの最小マッチで走査開始
<a ....>(ccc)</a>\G
aの最小マッチは以上のように見つかった。次の走査は( )内の文字列とする
対象の文字列は
cccである
E操作タグは, div, blockquote, a である。
divの最小マッチで走査開始
divは見つからない
blockquoteの最小マッチで走査開始
blockquoteは見つからない
aの最小マッチで走査開始
aは見つからない
見つからないので、Dの\G以降に相当する残りの抽出文字列まで戻る。
F対象の文字列は
りんご<a ....>deeeee</a><b>bb</b>
同様にdiv, blockquote, aで走査して
<a ....>(deeeee)</a>\Gが見つかり、
deeeee
G操作タグがないので、\G以降の
<b>bb</b>
が対象の文字列。同様にdiv, blockquote, aの操作タグはない。
Hここまでで、「未走査部分がなくなっているので」どんどん上へと戻ってゆき、
<blockquote>aaa★<div>この★〜★範囲は全部走査済</div>★<blockquote>
Aはdivから始めたので、
次のblockquoteを走査。
見つかったので、
<blockquote>(aaa★<div>この★〜★範囲は全部走査済</div>★)<blockquote>
aaa★<div>この★〜★範囲は全部走査済</div>★
の中に、div, blockquote, a の未走査は無い。
全走査終了
この例では特に何か処理をしたわけではなく、「走査」をしただけです。
内部がどうなったのか、状態によらず一定のパターン処理に当てはめればよいように
しました。
このような方向性の考え方が基本です。
空白文字や複数行に分かれているだのは、開始タグにアトリビュートが何か付いてい
るといったことは付属的な要素です。
正規表現や「1文字以上の空白文字」「シングルライン」などのオプションでいける
でしょう。
ライブラリの場合は自分で考慮する必要はありません。
全体的には「再帰」に属する概念です。
秀丸だと文字列型の変数にモテる文字数が多分不足するので、
そちらの方が問題になりそうですね。
|
|