Skip to main content

HTMLチックを解析したい

· 5 min read

ここ数日、HTMLチックの構文解析のコードを書いてる。 やりたいことはHTMLの解析に絡むんだけど、テキストの置換をしたいだけ。 なので、HTMLの仕様に沿っているか?というと、それほど沿ってない。 タグで括られたテキストをいじりたいなぁ〜ってことに対応する程度。 今後も曖昧なHTMLをさらに曖昧に書く人たちはいるだろうという推測も兼ね、必要最低限な解析で幅広く対応。

scala.util.parsing.combinatorを利用しているので、構文解析自体、似非かも?

実装していて思ったのは、(わかっていたけど)曖昧性が強いなぁ〜ってこと。 XMLならもっと簡単なのに・・・ってのが多い。 例えば、こんな感じ。

  • 閉じタグの省略。
  • 属性を " " で括る必要が無い。
  • 属性名しか存在しない。
  • scriptタグ内に "<" が存在する。

閉じタグを省略した場合、ルールに則って推測するのだが、これ、省略〜。 閉じタグ省略時は子要素としては扱いません。 インライン要素の場合は子要素にするとか、その程度の判断くらいは可能だけど、今回は "マークアップされたテキストの解析" を目的としているため、タグの名前は持ってない。 そのため、どれがインライン要素か?って情報は持ってないし、持ちたくない。 これで困ることがあるとしたら、その要素が置換対象となっていた場合。 それも、きちんとタグを閉じればいいわけだし、これくらいの制約はいっか、と判断。

HTMLに限らずだと思うけど、構文解析する場合、解析した結果、何かをしたいはず。 となると、解析前の情報はいらないことが多々あって、ホワイトスペース(改行とか空白とか)の情報って人が見やすくするためだけにあったりするのだが、今回は解析前の状態に戻したかったりもする。 解析前の状態に戻すということはホワイトスペースも必要になるので、この情報もきっちり取得してます。

字句解析に正規表現を使ってるので、処理速度が遅かったら本格的に書きなおさなきゃならないんだけど、どうなることやら。 今のところ、解析結果を保持するつもりだけど、保持の方法はまだ考えてない。 安易なのは、まんまオブジェクト(笑)

悩んだことがひとつ。 改行を含む文字列をなんでも取得したかったんだけど "." では取れなかった。 DOT ALLオプションも見当たらないし・・・と思って見つけたのが "[sS]" という表記。 "スペースとスペースじゃないもの" って、全部ってことじゃん!ってことで、解決。 相反するものの和を取ったら全部です(笑)