Perlコーディング初心者質問スレ Part 53
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2006/11/26(日) 14:38:23ID:SlmGsFMB【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc8.2ch.net/test/read.cgi/php/1153987463/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0230nobodyさん
2006/12/09(土) 11:36:47ID:???0231nobodyさん
2006/12/09(土) 17:43:35ID:???0232nobodyさん
2006/12/09(土) 21:29:28ID:???↓のスレッドにレス付けておきました。
Perlについての質問箱 28箱目
http://pc8.2ch.net/test/read.cgi/tech/1162273941/
0233nobodyさん
2006/12/10(日) 11:50:46ID:Mfd0yjZD例1:my $date = new Date;
例2:my $date_ins = new Date;
例3:my $date_obj = new Date;
例1だと、日付を格納する変数名と被るから、別の名前にしようと思うんだけど・・・
みなさんのご意見をお聞かせ下さい(´・ω・`)
0234nobodyさん
2006/12/10(日) 13:38:22ID:???スタイルはご自由に
0235nobodyさん
2006/12/10(日) 14:14:09ID:???$date = Date->new;
$data_obj = Date->new;
0236nobodyさん
2006/12/10(日) 14:16:42ID:???上のようなコードで、$date を受け取れますが、$date のみを受け取りたい場合にはどうすれば良いのでしょうか?
他を $hoge とかにすればいいという考えもできますが、それだと一度変数にいれるという処理が無駄であり
高速で処理をしたいので処理速度低下に繋がると思います。
シンプルな方法があれば教えて下さい。
たしか、変数部分に何かの定義済み定数をいれたら、その部分を受け取らないということになったようなきがしたんですが、
忘れてしまいましたorz
0237nobodyさん
2006/12/10(日) 14:28:59ID:???my( undef, $date ) = split /<>/, $line;
my( undef, $date, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef) = split /<>/, $line;
0239nobodyさん
2006/12/10(日) 15:35:39ID:???今時貧民的プログラミングをする必要はない、ログやロジックはシンプルにした方が良い、と思って掲示板作ったんですが、
速度が異常に遅いんです。
原因調べたら、掲示板のID生産のために crypt を使っているのですが、そこがとっても遅いんですね。
それを外したら100倍近いスピードに。
ようするにIPからIDを生成のために crypt を使っているんですが、表示のたびに全員分の生成をするので時間がかかるんです。
高速で実行できる crypt モジュールみたいのはないでしょうか?
0240nobodyさん
2006/12/10(日) 15:48:35ID:???書き込み時にcryptも作ってログに書けばおk。
time→書き込み日時も同様。
もしくは、ある程度ユニークな文字列が得られればそれで良いというのなら
cryptなんて使わなくても自分で適当なサブルーチン組めばいい。
0241239
2006/12/10(日) 15:53:23ID:???> 書き込み時にcryptも作ってログに書けばおk。
やっぱそうですよね(´・ω・`)
もう完成しちゃったし使用を開始しているので既にログがある状態なんです
・ファイルを読み取ってIDをファイルに書き込むプログラムを作る
・それを使って既にあるログにIDを追加する
・掲示板CGIへの投稿時にログにIDを追加するようにする
面倒ですが上の手順でやってみます
0242nobodyさん
2006/12/10(日) 16:04:54ID:???・新規の書き込みにはcryptでID情報を追加
・既存のID無しログはいちいちcryptするか適当な嘘IDを表示
というようにしておけばそのうち古いログが流されて問題なくなるよ。
なお、ログの修正をするのなら一度落としてきてローカルでやるように。
0243239
2006/12/10(日) 16:15:27ID:???なるほど…
ログは永久保存な仕様なんです
なので諦めてログ修正することにします
ローカルにはPerlとかインスコされてなくて面倒なので鯖でやることにします
専鯖なので負荷は余裕です>A<
0244nobodyさん
2006/12/10(日) 16:27:25ID:???> 専鯖なので負荷は余裕です>A<
(゚Д゚)ハァ?
俺の中に僅かに芽生えていたこいつに協力しようという感情が消滅した。
後はもう勝手にやってくれ。
0245nobodyさん
2006/12/10(日) 16:28:14ID:???2chに負荷がかからないように、差分のみを取得するようにしたいのですが。
0248nobodyさん
2006/12/10(日) 19:12:06ID:???差分取得の参考にでもして。
ttp://makegumi.no-ip.info:8080/src/makegumi1702.lzh.html
ハナモゲラ追加すれば今でも使えるはず。
板のdat取得は、subject.txtよめばいだけだから。
0249nobodyさん
2006/12/10(日) 22:53:28ID:???open(EN,"hoge.txt");
@old = <EN>;
close(EN);
これで@oldにファイルの中身(複数行)全て入ってますよね・・・?
リファレンス見ていたら益々分からなくなってきた(´△`;)
hoge.txtの中身をhoge2.txtに移すっていうのをやりたいのだけど
・・・動かねぇorz
0250nobodyさん
2006/12/10(日) 23:05:46ID:???open(EN,"hoge.txt");
read(EN, $buff, (-s EN));
close(EN);
でもおk
File::Copyとかとか♪
0252nobodyさん
2006/12/11(月) 01:30:10ID:???レスありです。
読み込んだ@oldを新たなファイルに書こうとすると
1行しか書かれず。。。
もう訳が分からないのでシンプルにファイルリネームで対応しました・・・。
0253nobodyさん
2006/12/11(月) 01:31:19ID:???読み込み&書き込みらへんのソース晒してみて
0254nobodyさん
2006/12/11(月) 16:28:57ID:???問題はurlのリンク記載なので修正すればいいと思うのですが、これがうまくいきません
以下の自動リンクの正規表現の置換部分で、リンクの記載内に「〜」がある場合、
強制的に「~」にする方法をご指導ください
$tmp_data =~ s/(https?\:\/\/[^\s|\:|\<]+)\.(\/?)([\-_\.\!\~\*\'\(\)a-zA-Z0-9\;\/\?\:\@\&\=\+\$\,\%\#]*)/<A HREF="$1.$2$3$4" TARGET="_blank">$1.$2$3$4<\/A>/ig;
0255nobodyさん
2006/12/11(月) 17:28:11ID:???0256nobodyさん
2006/12/11(月) 18:27:02ID:???0257nobodyさん
2006/12/11(月) 18:44:20ID:???Shift_JISのHTMLで書かれたフォームから送信すると
そういう不具合が起こることがある。
Shift_JISとユニコードの変換を厳密にやりすぎるからとか
どこかで読んだような気もするがどこだったかは忘れた。
まあ「safari チルダ」あたりでググると対処法とか色々出てくるよ。
0259nobodyさん
2006/12/11(月) 19:58:53ID:???また探してはみます
利用者にあれこれさせるのは難しいので、置換部分の
アドバイスがありましたら宜しくお願いします
0260nobodyさん
2006/12/11(月) 21:26:03ID:???ていうかShift_JISでフォームを書かなきゃいいんじゃね?
0261nobodyさん
2006/12/11(月) 23:07:25ID:???置換文字列を make_link みたいな関数にして /e で評価する。
その関数の中で 〜 → ~ の変換を行う。とか。
sub make_link {
my $url = shift;
$url =~ s/〜/~/;
return qq{<A HREF="$url" TARGET="_blank">$url</A>};
}
$tmp_data =~ s/(https?\:\/\/[^\s|\:|\<]+)\.(\/?)([\-_\.\!\~〜\*\'\(\)a-zA-Z0-9\;\/\?\:\@\&\=\+\$\,\%\#]*)/ make_link("$1.$2$3$4") /ieg;
0263nobodyさん
2006/12/12(火) 03:31:20ID:???$name=$FORM{'name'};
のように、nameを受け取ったとして、
複数選択されてるときhogeは、
どんな風に受け取ればよいでしょうか。
$hoge=$FORM{'hoge'};
ってすると、$hogeの値はhoge2になっているみたいなんです。
hoge1も受け取りたいのですが。
<INPUT type="text" size="20" name="name" value="">
<select size="〜" name="hoge" multiple>
<option value="hoge1" selected>hoge1</option>
<option value="hoge2" selected>hoge2</option>
</select>
よろしくお願いします。
0264nobodyさん
2006/12/12(火) 05:19:33ID:???0265nobodyさん
2006/12/12(火) 05:50:23ID:???ありがとうございます。
先ほど、CGI.pmで取得の仕方を解説してる
ページ見つけました。
動きが全然想像できないです。
CGI.pm使ってない方法検索しております。
よろしくお願いします。
0266nobodyさん
2006/12/12(火) 09:42:44ID:???って感じで入れてると思うけど、簡単に書いちゃうと
if(deinfed($forms{$name}){
$forms{$name} .= "\0" . $val;
}else{
$forms{$name} = $val;
}
のようにして、取り出すときは
my @tmpdata = split(/\0/, $forms{'hoge'});
とすれば複数選択したデータが @tmpdata に入ります。
ただしバイナリデータに対しては有効な技じゃないし、入力されたデータに対して \0 の存在をチェックし
エスケープしてやるなどの対策も考慮してください。
バイナリデータとか不正なデータをとりあえず無視して動作を確認したいなら上記可能。 なはずです
0267nobodyさん
2006/12/12(火) 10:31:41ID:???配列に叩き込むほうが手っ取り早いしわかりやすいのかも。
if ($name eq 'hoge') {
push @hoge, $value;
} else {
$FORM{$name} = $value;
}
>>266 =~ s/deinfed/defined/ のcgi-lib.pl方式でもいいし、あとは質問者さんの好みで。
0268nobodyさん
2006/12/12(火) 10:50:06ID:???訂正thx
0269nobodyさん
2006/12/12(火) 10:54:18ID:???hoge=hoge1とhoge=hoge2が順番に送られてくる
受け取ったものがhoge=hoge2になってるのは順番に同じ変数に入れてるから。
$hoge='hoge1';
$hoge='hoge2';
print $hoge;
こうなってるので後はどうするかは受け取り側で変えればいい。
0270nobodyさん
2006/12/12(火) 20:02:31ID:???例えば
&func(@list1,@list2);
としたら、funcの中で$list1[4]とか$list2[6]とかを参照したいんです。
0271nobodyさん
2006/12/12(火) 20:12:36ID:???0272nobodyさん
2006/12/12(火) 20:48:08ID:???&func(\@list1, \@list2);
0273nobodyさん
2006/12/12(火) 21:16:11ID:???&func( \@list1, \@list2 );
sub func {
my( $list1, $list2 ) = @_;
$$list1[4];
$$list2[6];
}
0274nobodyさん
2006/12/12(火) 21:23:56ID:???0275nobodyさん
2006/12/12(火) 21:50:20ID:???ってやったときに、foo/barが存在しないとエラーで死ぬんだけど、再帰的に掘ってくれるような
モジュールってない?ないんなら自前で組んでもいいけど、あるんなら再発明したくないし。
0276nobodyさん
2006/12/12(火) 22:12:56ID:???my @subdirs = split(/\/, shift);
my $curdir = curdir();
foreach my $subd (@subdirs){
mkdir $subd if !-e $subd;
chdir $subd;
}
chdir($curdir);
}
0278nobodyさん
2006/12/12(火) 22:18:53ID:???ttp://search.cpan.org/~stevan/Tree-Simple-VisitorFactory-0.10/lib/Tree/Simple/Visitor/CreateDirectoryTree.pm
0282nobodyさん
2006/12/13(水) 11:01:17ID:???File::Pathはデフォで入ってないっけ?
>>277
順序が保証されてるなんて書いてないだろ
順序は知らんがひとつずつ順番に入ってくるってのは合ってるんじゃね?
0283275
2006/12/13(水) 15:21:34ID:???ありがと。
>279
それやるとシステム依存するかなと思ってさ。
>280,282
ごめん、探し方が足りなかったみたい。吊ってくるorz
0284nobodyさん
2006/12/13(水) 16:44:36ID:???$n= 1000000;
if (($c1=chr(int($n / 256**2)))){
$n= $n % 256**2;
}
else { $c1= "\0"; }
if (($c2=chr(int($n / 256)))){
$n= $n % 256;
}
else { $c2= "\0"; }
$c= $c1 . $c2 . chr($n);
0285nobodyさん
2006/12/13(水) 16:52:52ID:???0287nobodyさん
2006/12/14(木) 13:53:01ID:???LWP::UserAgentなどを使用してCGIからアクセスするのは無理でしょうか?
一定時間経過するとセッションが切れて再ログインしないとダメだったり
サイト内での検索結果などをコピペするのがマンドクサイのです
0288nobodyさん
2006/12/14(木) 16:20:40ID:???やっぱ256**4で割るっきゃないか
0289nobodyさん
2006/12/14(木) 22:55:01ID:???0290nobodyさん
2006/12/15(金) 03:08:09ID:???ランダム数値を返すとなっていたので、7年間ずっと
rand(3)は0〜3までを返すと思っていたのですが、実際は
3未満(つまりは2.99999...)だったんですね。
上記の場合だと、3が出る確率は限りなく少ないことになる
ので今まで面倒なことをしてましたが、これから今まで
書いたプログラムの見直しをするようになるっぽいです。
一応同じように思い込んでた人のためになればと書き込
んでおきました。
0292nobodyさん
2006/12/15(金) 10:52:56ID:???$sex = substr(キーワード, カット開始位置, 文字数);
print "$sex<br>\n";
とするとたまに改行タグがおかしくなってしまう
print "$sex.<br>\n"
とすると改行タグはちゃんとされるけど・が$sexの後に表示されてしまう
0293nobodyさん
2006/12/15(金) 10:59:38ID:???0294nobodyさん
2006/12/15(金) 10:59:58ID:???「perl substr 日本語」でぐぐるといい
0295nobodyさん
2006/12/15(金) 12:26:12ID:???0296293
2006/12/15(金) 12:49:12ID:???$count= 5;
$s=~/(?:[\201-\237\340-\374]?.){$from}((?:[\201-\237\340-\374]?.){$count})/;
print $1,"\n";
0297293
2006/12/15(金) 12:56:47ID:???0298nobodyさん
2006/12/15(金) 13:54:29ID:???0299nobodyさん
2006/12/16(土) 14:00:26ID:???文字のマッチングしたいのですが、何をやってもうまくいきません。
どうか助けてください。
<例>
use CGI;
use Encode;
my $query = CGI->new;
foreach ($query->param() ){
$form{$_}=$query->param($_);
}
open (FILE,"<:encoding(shiftjis)","text.txt");
@aaa = split(//,<AAA>);
if ($form{bbb} eq $aaa[0]) {
print "一致";
}
close(FILE);
0300nobodyさん
2006/12/16(土) 14:02:20ID:???<訂正>
open (FILE,"<:encoding(shiftjis)","text.txt");
@aaa = split(//,<FILE>);
if ($form{bbb} eq $aaa[0]) {
print "一致";
}
0302299
2006/12/16(土) 16:25:29ID:???htmlのフォームに入力された文字と、txt(本当はcsv)のデータとが合致するときに、
なにかを表示するという簡易なデータベースを作っているところなんです。
open (FILE,"<:encoding(shiftjis)","text.txt");
とかでtxtを開いて、クエリと合致するかどうかをみたいのですが、
cgi.pmでデコードした文字(クエリ)と、openで開いた文字の
デコード(?)が違うようで、他のコーディングとやらの
何をやっても一致しないという状態に陥ってます。
ものすごく初歩的・根本的な間違いをおかしているとは思います。
0303nobodyさん
2006/12/16(土) 16:36:16ID:???text.txtのカンマ区切りのデータとフォームが一致するかを見たいということかな?
text.txtは1行のみ?
改行は入っている?
split /,/, <FILE>; じゃだめ?
文字コード気にする前に、単純な英数字で確認してみて。
0304299
2006/12/16(土) 18:07:20ID:???>>299のようにクエリを受け取ってから、
自分のやりたいことをカンタンにしたのが下記のプログラムです。
open (FILE,"<:encoding(shiftjis)","aaa.csv");
while(<FILE>) {
@aaa = split(/,/,$_);
foreach(@aaa) {
if ($form{namae} eq $aaa[$i]) {
print encode("shiftjis","$aaa[$i]:match<br>");
} else {
print encode("shiftjis","$aaa[$i]:---<br>");
}
$i++;
}
$i =0;
}
close(FILE);
カンマ区切りのデータとフォームの一致をみるのが目的で、
csvは複数行に渡っています(改行入り)。
半角英数の場合はマッチングできるのですが、
平仮名・漢字は一致しません。
また、半角英数・仮名漢字に共通して、
open FILEで引っ張ってきた@aaa{$1}を表示しようとすると
文字化けが起こってしまいます。
0305nobodyさん
2006/12/16(土) 18:35:53ID:???ひとまず、エンコードの処理を忘れて、全てのファイルの文字コードを統一して保存して下さい。
次にコードをシンプルにして、試してみましょう。
open FILE, 'aaa.csv' or die;
while( <FILE> ){
chomp;
my @aaa = split /,/;
for( my $i = 0; $i < @aaa; $i ){
print $form{namae} eq $aaa[$i] ? 'true' : 'false';
}
}
close FILE;
余計なお世話だけど、そんなforeachの使い方教えてるところは参考にしないほうがいいと思われ。
0306nobodyさん
2006/12/16(土) 19:07:56ID:???0307nobodyさん
2006/12/16(土) 20:54:54ID:???こっちのが書くの楽だろ常識的に考えて
楽と云うよりも効率が良くなったからこちらの方が良さそうな。
という思想で。
それはそうともう $i とはもう書かなくなったよなぁ。。。
ついでに回数を指定したループも書かなくなったよなぁ。。。
0309nobodyさん
2006/12/16(土) 22:24:50ID:???0310nobodyさん
2006/12/16(土) 22:27:29ID:???0311299
2006/12/16(土) 22:32:58ID:???アドバイスの通りにしたら無事解決しました。
結局エンコード云々はいじらないでよかったようです。
ありがとうございました。
0312nobodyさん
2006/12/16(土) 22:42:14ID:lMy9T+vRperlに触れて2日目です。。かない痛いミスしてるかもしれませんが、何方か教えてください。
Flashからcgiへ変数$nameを渡す実験をしているのですが、$nameを日本語にすると
すべて文字化けしてしまいます。手元にある入門書を参照したところ、jcode.plを使えばよいとあったので、
require 'cgi-lib.pl';
require 'jcode.pl';
&ReadParse(*name);
&jcode::convert(*name,'sjis');
print "$name";
としたのですが、まだ文字化けします。sjisにしてもeucにしても同じ結果です。
どうすればよいでしょうか。jcode.plが存在するディレクトリは確認しました。
0313nobodyさん
2006/12/16(土) 22:55:56ID:???&jcode::convert(\$name{$_},'sjis');
}
0314nobodyさん
2006/12/16(土) 23:05:09ID:lMy9T+vR0316287
2006/12/17(日) 12:12:23ID:???java.lang.NullPointerException のみが出力されてくるのですが、御教示お願いします。
use LWP::UserAgent;
$url = "https://example.com/test.jsp"; #実際にはログイン画面のURLが入ってる
$ua = LWP::UserAgent->new;
$req = new HTTP::Request GET => $url;
$res = $ua->request($req);
print "Content-type: text/html\n\n";
print $res->content;
0318287
2006/12/17(日) 13:35:07ID:???やっぱ皆さんこういう高度なのもサクっと作ってcron自動化とかしてたりするんでしょうか
ID・PASSなどをフォームに入れるログイン作業程度なら、
ローカルHTMLのformにhiddenで入れてしまって、jsで一発ログインとかしてるのですが、
一定時間ごとに自動ログイン→一連の作業→処理保存までするのは難しいですね。
もっと色々頑張ってみます
その点、LWPモジュールも然りサンプルが必ずと言っていいほど掲載されているので、熟読すると良いかもしれませんです♪@CPAN
あっと、そのときには、解説の英文を1から10まで読むよりも、サンプルを1から10まできっちりと読むと判りやすいかと♪
0320nobodyさん
2006/12/17(日) 15:56:53ID:8qXdAMYDwww.xxx.com/aaa.php?id=1&next=1
nextの1で処理を行っているのですが
リロードでも有効になってしまいます。
これを回避する方法などありますでしょうか。
submitからなら対策できるのですが、埋め込んだURLからは
どうしたら回避できるかわからず詰まっています。
0321nobodyさん
2006/12/17(日) 15:58:27ID:8qXdAMYD0323nobodyさん
2006/12/18(月) 16:04:35ID:otF+VpE2POSTで$nameを送信($nameは日本語)
↓
cgi側が$nameを受け取って、namelist.datをオープンして、$nameを書き込んでクローズ。
↓
namelist.datを開くと、日本語が%83g%83%7D%83gといった感じで書き込まれている。
これを直したいのですが、namelist.datに書き込む前にjcodeで変換しても駄目でした。
文字コードはsjisで統一してあります。どのようにすれば文字化けせずに書き込めるのでしょうか。
0324nobodyさん
2006/12/18(月) 16:09:24ID:???0325nobodyさん
2006/12/18(月) 16:27:36ID:otF+VpE2>>324
お手数かけました。
0326nobodyさん
2006/12/18(月) 20:56:29ID:???print "Content-type: text/html\n\n";
print <<EOS;
<HTML lang="ja">
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<TITLE>$_[0]</TITLE>
</HEAD><BODY>
$_[1]
</BODY></HTML>
EOS
exit;
}
POSTされた文字列が不正だった場合等に、ちょっとしたエラー出力をするのに、
こんな感じで単純な出力をするサブルーチンを作って実行するのと、
print "Content-type: text/html\n\n";
print <<EOS;
<HTML lang="ja">
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<TITLE>エラー</TITLE>
</HEAD><BODY>
えらーです
</BODY></HTML>
EOS
exit;
}
そのままサブルーチンを作らずにHTMLを出力するのとではどれくらい速度に違いが出たりするのでしょうか。
0327nobodyさん
2006/12/18(月) 21:00:45ID:???またはテンプレート化する。
しかし、速度を気にするほど頻繁にエラー画面が出てしまう設計はどうかと。
0328nobodyさん
2006/12/18(月) 21:03:25ID:???0329nobodyさん
2006/12/18(月) 21:14:08ID:???どうもです。
エラーは極力でないように、悪意に対応できるようには作っているつもりなんですが
なんせ自分で一から作るのは初めてなもので、単純に速度が気になったのです。
それほどアクセスが掛かるようなものでもないですし、自分で使う分にはエラーなんて出さないように使うので
そんなに問題でもないんですが一応。
>>328
具体的にはどうすればよいのでしょうか。
print "Content-type: text/html\n\n";
はサブルーチンにせずに都度出力すると言うことでしょうか。
■ このスレッドは過去ログ倉庫に格納されています