あと味

たくさん情報を食べて、たくさん発信すると、あとになって味わい深い。

HTMLファイルのname属性を取得

今日、HTMLに記述されているフォームの部品につけた名前の一覧を出力するプログラムをPerlで書きました。

その部品の数なんですが、なんと80個超です!もちろんそれ以外の記述も盛りだくさんなわけで目で確認していくと非常にまいります。ということで慣れていない正規表現を使ってプログラムを書きました。これが思った以上に時間がかかりました。

書いたプログラムはこれです。

use strict;

open HTML, "<index.html";
open OUTPUT, ">output.txt";
close OUTPUT;
open OUTPUT, ">>output.txt";
my $i = 1;
while (){
    next if /name="\..*?/;
    next if /type="hidden"/;
    if (/(name=".*?").*?(name=".*?")/) {
	print OUTPUT sprintf("%4d", $i), "行目: $1 $2\n";
    }
    elsif (/(name=".*?")/) {
	print OUTPUT sprintf("%4d", $i), "行目: $1\n";
    }
    $i++;
}
close OUTPUT;
close HTML;

出力結果はこれ。

f:id:jdg:20060912010743j:image

ベテランの方からすれば文句の付けどころだらけなのかもしれません。

.(ピリオド)から始まるname属性の値はsubmitボタンに使用していたものだったので正規表現で除いて、同様に隠しフィールドのname属性もいらなかったため除きました。1行に2箇所のname属性がある行があったため2箇所までは対応できるようにしました。最終的に、行数が該当箇所と同時に表示されるようにしたので編集作業の助けになりそうです。また、見やすくするためにsprintfで桁数も揃えました。このHTMLファイルの行数は最大4桁あるんです。。。

ちなみにこのプログラムは自分専用のものですので、そのまま使っても意味がないと思います。

正規表現とは違う方法でも試しましたが、こちらは5分もかかりませんでした。CGI.pmのparam関数を使ってすべてのパラメータを取得する方法です。

use strict;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);

my @p = param;
print header;
print start_html;
for (@p) { print p("$_"), "\n" }
print end_html;

オブジェクト指向タイプではなくオールドタイプを使いました。正規表現の時のように必要のない部分にフィルタをかけることはできませんでしたがとにかく楽でした。解析しているHTMLファイルのaction属性の値をこのコードのcgiファイルにすれば、submitボタンクリック後ブラウザ上で確認できます。

このプログラムは誰が使用しても同じ結果になると思います。

ともかく正規表現のほうは何かと苦労しましたが、こういう処理がサクサク書けるようになったらよいと思いました。