• ベストアンサー

cgi+htmlテンプレート使用

「cgiファイルからhtmファイルを読み込んで、部分的に差し替えの上、再度htmファイルに書き出す」ということを考えています。 で、htmファイルのソースの中に<-- start --><-- end -->のようなタグを仕込んでおいて、cgiの方からその間の部分に情報を挿入するという形を考えています。 具体的には、 open(IN, $htm_file) || error("読込エラー"); print "Content-type: text/html\n\n"; while (<IN>) { if (.....<--start-->があったなら......) { .......$jouhouを挿入する........ } ........................................ } close(IN); のような感じを漠然と想定しているのですが、どんなもんでしょうか。どうやってやればイイのか、検討がつかないもので。うまいやり方を、お分かりの方がいましたら教えていただけませんか。

質問者が選んだベストアンサー

  • ベストアンサー
  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.5

書いた本人にも100%理解できていないのでうまく説明できる自信もありませんが・・・ ((?:(?!<!-- end -->).)*) を内側のカッコから分解すると (?!<!-- end -->) → <!-- end -->ではない (?:~.) → 任意の一字(後方参照を作らないグループ化) (~*) → 0回以上の繰り返し 要約すると <!-- end -->ではない任意一字の0回以上の繰り返し→ (<!-- start -->の後ろから)<!-- end -->までの間の0桁以上の任意の文字列。

benneb
質問者

お礼

恐れ入りました。 いろいろイジって(ピリオドをとってみたりとか)試してみましたが、この式のままでないとうまく動きませんね。 いろいろと勉強になりました。 ありがとうございました。(^з^)-☆Chu!!

その他の回答 (4)

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.4

> $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; > の1行について、くわしく解説いただけないでしょうか。 やろうとしているのは <!-- start -->何か<!-- end --> を <!-- start -->$data[n番目]<!-- end --> に置換しています。 細かい事についてはとにかく正規表現について読み漁ってください。 参考URLに必要なことは全部書いてあると思います。 キーワードは ・置換 ・正規表現 ・s///演算子用オプション、gとs ・文字列のグループ化と後方参照 ・拡張構文、(?:..)と(?!式) 等々。。。

参考URL:
http://www.rfs.jp/sitebuilder/perl/02/09.html
benneb
質問者

補足

詳細な解説ありがとうございます。 いや~、拡張構文ですか・・・ε-(´o`)) 正規表現って驚きですね。 で、 ((?:(?!<!-- end -->).)*) の部分だけがどうしても分かりません。もし気の向くことがあったなら、アホな私メに教えていただければありがたいです。

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.3

思いっきり簡単に書くと以下のようになります。 (正規表現のあたりはもっと簡潔に書けるかもしれませんがあまり得意でないので。) あとは、置換するデータを入力フォームから受取るとかCGIとしての一般的な体裁を加えれば実用的になるかと思います。 #!/usr/bin/perl my @data = qw{123 ABCD あいうえお};# 置換するデータ my $count = 0; #読み込み open IN,'hoge.html'; read IN, my $buf, -s 'hoge.html'; close IN; #置換 $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; #書き出し open OUT,'> hoge.html'; print OUT $buf; close OUT; #終了メッセージ print <<__MESSAGE__; Content-type: text/html; <html> <head> <title>完了</title> </head> <body> <h1>完了</h1> <p>$count 置換完了</p> </body> </html> __MESSAGE__ なお、テンプレートを扱うといっても、本件ではそのテンプレート自体を更新しようとしている(置換のための制御文を残さないといけない)のでHTML::Templateモジュールはあまり向いていないと思います。 もちろん、テンプレートと表示/更新するファイルを分ければ問題ないのですが。

benneb
質問者

補足

回答ありがとうございます。 これ、うまいこと動きますね。 もしよろしければ、 $buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg; の1行について、くわしく解説いただけないでしょうか。 (当方、cgi学習始めたばかりなもので・・・。話は別ですが、このgooの掲示板のシステム、分かりにくいですね。使い方がまだ良く把握できてません(涙)。)

  • steel_gray
  • ベストアンサー率66% (1052/1578)
回答No.2

ご本人がおっしゃるとおり漠然としすぎてあまり具体的な回答は難しいのですが、start / end が一組だけなら正規表現を使った置換でも充分だと思います。 あと、参考URL(のa-Update)のような配布物もあるので検討してみては?(条件によっては有料です。) 話はそれますが、 <-- start --><-- end -->よりも <!-- start --><!-- end -->のほうがHTMLとしては格好がいいかと思います。

参考URL:
http://www.appleple.com/cgi/
benneb
質問者

お礼

回答ありがとうございます。 挿入箇所は複数ある上に、 htmソース中の<!-- start --><!-- end -->の間をカットしたいのです。 ちょっと無理っぽいですかね。 おすすめのツール、参考にしてみます。

  • you-m
  • ベストアンサー率58% (190/327)
回答No.1

いわゆるテンプレートライブラリというものがあります。 Perlの場合は、HTML::Templateモジュール が有名ですかね。CPANで探すと似たようなモジュールがたくさん見つかります。車輪の再発明を嫌うならこういうものを活用するのがいいと思います。 自作のライブラリをするのであっても、こういう既成のライブラリのソースは参考になると思いますよ。 解説系の情報もありますが、たいてい個人サイトなので、ここには載せられません。サーチエンジンで検索してみてください。

benneb
質問者

お礼

回答ありがとうございます。 HTML::Templateモジュールのことは知ってはいたのですが、ちょっと調べてみます。 質問者が掲載するのもナンですが、 http://homepage3.nifty.com/hippo2000/perltips/html/template.htm が分かりやすそうです。

関連するQ&A