Perl覚え書き20041128

 昨日書くのを休んだ。前回書いた物の解決策が思い浮かばなかったからというのが理由。それなら別の何かを書けばいいのかもしれないけど、何かいい方法がないかと常に気になってしまって集中できないから辞めた。見に来てる人もほとんどいないしまあいっかってことで。

 さて今回はかなり変わっている。この関数のキモとなる部分を作り直したと言っても過言ではないぐらいに。それに伴ってExportする関数がconvTagsAllだけになった。別にconvTagを使ってもかまわないが、ちょっと使い方が違うと思うから素直にconvTagsAllを使うようにしよう。

 一体どんなところが変わったのか。それはタグ内の要素の探索方法。

 これまではそのタグが正しい書式で書かれていることを前提に、まずスペースで要素の塊を分割し、そのそれぞれを=でkeyとvalueに分解した。ただしvalueの中に=が含まれている可能性があるため、"や'で囲まれている文字列にある=はあらかじめ別の文字に変換しておき、あとで元に戻すという方法を採っていた。

 普通はこれで問題ない。ちゃんと内容が取得できるが、"や'の対応が合っていないとおかしなことになってくる。

 そこで、それぞれの場面での区切り文字を順番に調べていくことによって内容を取得するようにした。

 まずkeyは、先頭からスペース、=、>が出てくるまでがそれにあたる。たとえば <input type="text" disabled readonly> というタグがあったとする。typeの後ろには=があるし、disabledの後ろにはスペース、readonlyの後ろには>がある。

 続いてvalue。上記の例のdisabledの様にvalueを持たない物もある。それは=があるかどうかで判断する。valueが"や'で始まっている場合は次に"や'が出てくるまで。もちろん開始のクオート文字に合わせる。もし先頭が"や'で始まっていないのに後に"や'が出てきた場合はそれは省略しているものと見なし、プログラムの都合上クオートを補う。valueがクオートされていないときにスペースや>が出てきたとなればそこでvalueが終わっているとする。

 それをループで回し、タグが終わってると判断できたところでループを終わる。ここで無限ループを使っているため、食わせたタグによってはループが終わらないという可能性もある。CGIでこの関数を使うときは、実行時間制限があるため無限ループから抜けられない場合はkillされてInternal Server Errorが出るとは思うが注意して欲しい。つまりは自己責任で。

 与えられた文字列の途中でタグが終わったと判断された場合は、残った文字を次の処理に回す。

 何やら変なタグが出力されることもあるが、ブラウザで見てみると同じ結果が出てるみたいだからたぶん大丈夫だろう。

 大丈夫だろうとは思うけど、一番いいのはちゃんとしたタグを食わせることだ。そりゃ当たり前か。
 今回のソースはここ