プロが教える店舗&オフィスのセキュリティ対策術

「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);

のような感じを漠然と想定しているのですが、どんなもんでしょうか。どうやってやればイイのか、検討がつかないもので。うまいやり方を、お分かりの方がいましたら教えていただけませんか。

A 回答 (5件)

書いた本人にも100%理解できていないのでうまく説明できる自信もありませんが・・・



((?:(?!<!-- end -->).)*)
を内側のカッコから分解すると

(?!<!-- end -->)
→ <!-- end -->ではない

(?:~.)
→ 任意の一字(後方参照を作らないグループ化)

(~*)
→ 0回以上の繰り返し

要約すると
<!-- end -->ではない任意一字の0回以上の繰り返し→
(<!-- start -->の後ろから)<!-- end -->までの間の0桁以上の任意の文字列。
    • good
    • 0
この回答へのお礼

恐れ入りました。
いろいろイジって(ピリオドをとってみたりとか)試してみましたが、この式のままでないとうまく動きませんね。

いろいろと勉強になりました。
ありがとうございました。(^з^)-☆Chu!!

お礼日時:2005/05/31 15:30

> $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

この回答への補足

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

補足日時:2005/05/30 22:44
    • good
    • 0

思いっきり簡単に書くと以下のようになります。


(正規表現のあたりはもっと簡潔に書けるかもしれませんがあまり得意でないので。)
あとは、置換するデータを入力フォームから受取るとか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モジュールはあまり向いていないと思います。
もちろん、テンプレートと表示/更新するファイルを分ければ問題ないのですが。

この回答への補足

回答ありがとうございます。
これ、うまいこと動きますね。

もしよろしければ、
$buf =~ s/(<!-- start -->)((?:(?!<!-- end -->).)*)(<!-- end -->)/$1$data[$count++]$3/sg;
の1行について、くわしく解説いただけないでしょうか。

(当方、cgi学習始めたばかりなもので・・・。話は別ですが、このgooの掲示板のシステム、分かりにくいですね。使い方がまだ良く把握できてません(涙)。)

補足日時:2005/05/29 12:05
    • good
    • 0

ご本人がおっしゃるとおり漠然としすぎてあまり具体的な回答は難しいのですが、start / end が一組だけなら正規表現を使った置換でも充分だと思います。



あと、参考URL(のa-Update)のような配布物もあるので検討してみては?(条件によっては有料です。)

話はそれますが、
<-- start --><-- end -->よりも
<!-- start --><!-- end -->のほうがHTMLとしては格好がいいかと思います。

参考URL:http://www.appleple.com/cgi/
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/05/29 06:09

いわゆるテンプレートライブラリというものがあります。


Perlの場合は、HTML::Templateモジュール が有名ですかね。CPANで探すと似たようなモジュールがたくさん見つかります。車輪の再発明を嫌うならこういうものを活用するのがいいと思います。
自作のライブラリをするのであっても、こういう既成のライブラリのソースは参考になると思いますよ。

解説系の情報もありますが、たいてい個人サイトなので、ここには載せられません。サーチエンジンで検索してみてください。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
HTML::Templateモジュールのことは知ってはいたのですが、ちょっと調べてみます。

質問者が掲載するのもナンですが、
http://homepage3.nifty.com/hippo2000/perltips/ht …
が分かりやすそうです。

お礼日時:2005/05/29 06:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!