トップページ⇒php
1001コメント343KB

【Perl】初心者コーナー Part13

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/05/30 13:06ID:R2kt1mTx
いらっしゃーい、Perlの「コーディング」で困ってる人のスレです。

1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。

1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

CGIの質問は【CGIだけど、なんか質問ある? part 6】
http://pc.2ch.net/test/read.cgi/php/1019561283/
参考書籍の話題は【【Perl,CGI】参考書籍 第2版】
http://pc.2ch.net/test/read.cgi/php/988809842/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般】
http://pc.2ch.net/test/read.cgi/php/991313362/
スクリプトの改造依頼は 【スクリプト改造工房 Part4】
http://pc.2ch.net/test/read.cgi/php/1012839651/

過去ログ、その他の役立ち情報は>>2-10あたりを見よう。
0655nobodyさん02/07/06 13:16ID:???
>>654


  少  し  は  勉  強  し  よ  う  っ  て  気  は  な  い  の  か


0656Saru02/07/06 13:21ID:CFBQ9es6
Perlでテキスト処理に関して、2桁の数字だけを削除したい場合は
どのようにかいたらいいんでしょうか?
今は
s/[0-9]{2}//g;と書いてます。
1桁の数字は残しておきたいんですが…。
どなたかヒントでもよいので教えてください。お願いします。
0657nobodyさん02/07/06 14:01ID:???
s/^[0-9]([0-9])$/$1/g;
0658Saru02/07/06 14:16ID:CFBQ9es6
>657さん
困っていたのでとても助かりました。
どうもありがとうございます!
0659nobodyさん02/07/06 14:32ID:???
s/(\D)\d{2}(\D)/$1$2/g;
0660nobodyさん02/07/06 14:54ID:???

今クリック数をカウントするCGIを作ってるのですが、
クライアントから送られてくるデータが

id=1&url=http://www.***.com/

だったばあい、

$idの中身を1に
$urlの中身をhttp://www.***.com/

にしたいのですが、今は

$data = $ENV{'QUERY_STRING'};
@data = split(/\&/,$data);
$id = $data[0];
$url = $data[1];
%id = split(/\=/,$id);
%url = split(/\=/,$url);

となんとも効率が悪いやり方なのですが自分の知識ではこのようにしか
やり方が分からないのですがもっといいやり方は無いでしょうか?

それともし$dataに「&と=」が無かった場合はexitで終了させたいのですが
どのように調べればいいのでしょうか?

よろしくお願いします。
0661nobodyさん02/07/06 15:02ID:???


$buffer = $ENV{'QUERY_STRING'};
if (($buffer !~/&/ )&&($buffer !~/=/){exit;}
local(@pairs) = split(/&/,$buffer);
foreach $pair(@pairs){
local($name,$value) = split(/=/,$pair);
$FORM{$name} = $value;
}
0662nobodyさん02/07/06 15:03ID:???
 ) がひとつ足りなかった。
0663nobodyさん02/07/06 15:12ID:???
&と=が正規表現で調べることが出来ることは分かったのですが、

$FORM{$name} = $value;

これは%FORMというハッシュの中にkeyが$nameでvalueが$valueというのを
代入してる処理なんでしょうか?

0664nobodyさん02/07/06 15:17ID:???
local(@pairs) = split(/&/,$buffer);
この処理で、
id=1&url=http://www.***.com/ を
id=1 url=http://www.***.com/ に分割し(@pairsに)
foreach $pair(@pairs){
local($name,$value) = split(/=/,$pair);
$FORM{$name} = $value;
}
で それらをさらに分ける。
$FORM{$name} = $value;
は
$FORM{id} = 1;
$FORM{url} = http://www.***.com/;
になるから%FORMに入れられる。あとはこれらを自由に処理するだけ。
0665nobodyさん02/07/06 15:20ID:???
>>664

なるほど。理解できました。ありがとうございます。

ちなみにローカル変数はサブルーチン内で使うものでわなかったでしょうか?
サブルーチン化したほうがいいのでしょうか?
0666Saru02/07/06 15:21ID:CFBQ9es6
>659さん
こちらは2桁ともに削除できるんですね。
勉強になります…!ありがとうございます。
0667nobodyさん02/07/06 15:22ID:???
ちなみに

split(/=/,$pair);

これは

=の前に\を入れてエスケープするんですよね?
0668nobodyさん02/07/06 15:31ID:???
エスケープしないで使ってる人が多いな。
たいていはサブルーチン化して、GETもPOSTも対応してる。

local($pair,$buffer);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
$buffer = $ENV{'QUERY_STRING'};
}
local(@pairs) = split(/&/,$buffer);
foreach $pair (@pairs) {
local($name,$value) = split(/=/,$pair);
$FORM{$name} = $value;
}
0669nobodyさん02/07/06 16:42ID:up0NZwlm
open(FILE, "./log.log") で作成したログのパーミッションが 644 で生成されるんですが、
これを 600 で生成されるようにするにはどうすればよいでしょうか?
CGIはユーザー権限で動いています。
おながいします。
0670nobodyさん02/07/06 16:45ID:???
まちがった・・ open(FILE, ">./log.log") でした
0671nobodyさん02/07/06 16:48ID:???
>>670
umask
0672nobodyさん02/07/06 16:51ID:up0NZwlm
>>671
umask関数ですね。検索して調べてみます。
067366902/07/06 17:06ID:???
umask 066; でできました。 >>671 さんありがとうございました。
0674nobodyさん02/07/06 17:42ID:stglrVc7
open,umaskとするよりsysopen使うのがおすすめだぞ。
openよりはセキュアかもだしな。
067566902/07/06 18:30ID:???
>>674
もうできたからいいよ。っつーか書くのがおせーよ!
氏ね!
0676nobodyさん02/07/06 18:33ID:???
>>675

偽者ケテーイ
0677nobodyさん 02/07/06 21:50ID:pjFxin79
perl初心者です。Activeperlのプログラムを動かしてInternetExplorerを起動したいんですが
どのようにすればよいでしょうか?
0678nobodyさん02/07/06 21:53ID:???
exec(C:\Program Files\Internet Explorer\IEXPLORE.EXE);

`C:\Program Files\Internet Explorer\IEXPLORE.EXE`
0679nobodyさん02/07/06 23:30ID:Jm7Ff5yb
レンタルサーバーでsendmailが使えない場合、ほかにメールを送る方法ってありますか?
0680nobodyさん02/07/06 23:31ID:???
Net::SMTP
0681nobodyさん02/07/07 01:52ID:iHDNP1fk
JavaScriptをperlに書き換えたいのですが
★の部分の書き方がわかりません。(ぺこり)
他も間違いありましたら教えて下さい。
-------------------------------------
functuon myfun{
P=document.F.E1.value+document.F.E2.value+document.F.E3.value;
T=0;
for(i=0;i<P.length;i++){T=T+eval(P.charAt(i))}
if((T==11)||(T==22)){document.F.E4.value=hoge[T]}
else{while(T>=10){T=T-9;}
document.write(hoge[T])
}
-----------------------------------------
foreach $data ( @buf ){
( $name , $value ) = split( /=/ , $data );
$FORM{$name} = $value;
@list = values %FORM
};

$P = $list[0]+$list[1]+$list[2];
$T = 0;
for($i=0; $i<★; $i++){$T=$T+★($i)};
if(($T==11) || ($T==22)){$list[4]=hoge[$T];}
else{while($T>=10){$T=$T-9;}}
print "hoge[$T]";
0682nobodyさん02/07/07 02:06ID:???
>>681
せめて変数が何あらわしてるかぐらい書け。
068368102/07/07 02:18ID:iHDNP1fk
>>683
整数
document.F.E1.value
document.F.E2.value
document.F.E3.value

計算をするための作業用の変数
P
T

Pのlengthを取得するためのカウンター用の変数
i

他のはformに入力された値を取得するための変数です
0684nobodyさん02/07/07 02:32ID:???
とりあえずこんな感じ

for($i=0; $i<★; $i++){$T=$T+★($i)};
↓
for($i=0;$i<length($P);$i++){$T=$T+substr($P,$i,1)}
068568102/07/07 08:45ID:???
>>684さん
おはようございますっ♪
あ〜感謝!うれしいです。

0686nobodyさん02/07/07 12:56ID:xpVArwn6
「http://サーバー名/CGIスクリプト名?データ」で実行し、
データの受け渡しをするプログラムを作っているんですが、
他のURLへジャンプさせるときに、
<A HREF="http://***/CGIスクリプト名?ジャンプ先URL">ジャンプ</A>
としたいんですが、ジャンプ先URLをフルパスで出せるようにするには
どうしたらいいですか?以下がつくった内容です。
my($encoding) = @_;
my($method) = $ENV{'REQUEST_METHOD'};
if ($method eq 'GET') { $query = $ENV{'QUERY_STRING'}; }
elsif ($method eq 'POST') { read(STDIN, $query,
$ENV{'CONTENT_LENGTH'}); }
local(@query) = split(/&/, $query);
foreach (@query) {
tr/+/ /;
($key, $val) = split(/=/);
$key =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge;
$val =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge;
$val =~ s/\r\n/\n/g;
$in{$key} = $val;
}
my $req = new HTTP::Request POST => $val;
$req->content_type('application/x-www-form-urlencoded');
$req->content('match=www&errors=0');
my $res = $ua->request($req);
if ($res->is_success) {
$myd = $res->content;
$myd =~ s/(\<A HREF=\")/$1test.cgi?/g;
print $myd;
} else {
print "No!";
}

今の状態ですと、
$myd =~ s/(\<A HREF=\")/$1test.cgi?/g;
をやると、
<A HREF=test.cgi?test/index.html> というような感じになって
<A HREF=test.cgi?http://www.***.co.jp/test/index.html>;
というような形になりません。
0687nobodyさん02/07/07 16:41ID:???
入力データをハッキリと明示しないと答えようがないだろ。
入力データをハッキリさせたら正規表現スレで質問すべき問題だろ。
0688nobodyさん02/07/07 20:52ID:ZrDEUCOM
> 687
686です。
<A HREF="http://www.test.co.jp/test.cgi?http://www.test.co.jp/next.html">ジャンプする</A>
正規表現スレでやればいいんですか?
それ以前のヴァカなもので、初心者スレで書き込んだんですが、
それも場違い?
答えも見つからず、困っていたのに(泣)
0689nobodyさん02/07/07 21:33ID:???
リンクを表示させるだけなら
$link= qq(<A href="CGIのURL?$ENV{'QUERY_STRING'}">XXXへのリンク</A>);
0690nobodyさん02/07/08 16:37ID:???
フォームから入力された文字の最大数を制限するとか、
半角数字以外が入力されたらエラーメッセージを返すとか

どう呼ぶのかわからないのですが、
よく使われる処理のモジュールというかライブラリーと言うのか
そんな感じのものを探すにはどうしたら良いですか?
googleしてみましたがキーワードが甘いらしく見つかりませんでした

0691nobodyさん02/07/08 16:38ID:ZsVGz1/q
age忘れました
0692nobodyさん02/07/08 16:41ID:???
文字数を制限するなら、$ENV{'CONTENT_LENGTH'}の値を見るとか。
 送られてきたデータが /[^0-9a-zA-Z}/ 以外なら die とか。
0693nobodyさん02/07/08 16:45ID:ZsVGz1/q
超即レス thank you!です。
0694nobodyさん02/07/08 17:12ID:E09xqBbE
たとえば(3,3,10,6,1)という配列があって、コレをソートすると
1 3 6 10と返ってきてしまうのを、どうにかして
1 3 3 6 10にできないものでしょうか・・・?
0695nobodyさん02/07/08 17:31ID:???
>>694

@data = (3,3,10,6,1);

@sort_data = sort
{
$a <=> $b;
} @data;
0696nobodyさん02/07/08 22:12ID:Hy1uHDxp
> 689
それだと、受け取ったURLそのまま出ちゃうんじゃないかい?
0697nobodyさん02/07/08 23:54ID:HDd0iUwW
ARGVって何?どうやって読むの?アーグブイ?
0698nobodyさん02/07/09 00:04ID:???
ARGment Value
0699nobodyさん02/07/09 00:05ID:???
argument だた。。。
0700nobodyさん02/07/09 00:06ID:???
麻酔をせずに歯を削られているような気分で、
「アァァァーグヴィ!」

じゃなかったっけ?
0701nobodyさん02/07/09 00:11ID:???
なるほど納得!
0702 02/07/09 00:21ID:???
SOCKET使って外部のCGIにPOSTしてみたいのですがなかなかうまくいきません。

FORMを取得して
$post_mes="[email protected]&wcomment=test";
って感じにして(多分ここが違う?)

# POST
print SOCKET "POST $check_host HTTP/1.1\r\n";
#HTTP_REFERERを送信
print SOCKET "REFERER: $referer \r\n";
#User-Agentを送信
print SOCKET "User-Agent: $agent \r\n";
print SOCKET "X_FORWARDED_FOR: $xfor \r\n";
print SOCKET "Accept: */* \r\n";
print SOCKET "Accept-Language: ja \r\n";
print SOCKET "Accept-Encoding: gzip \r\n";
print SOCKET "\r\n";
print SOCKET "Content-Type: application/x-www-form-urlencoded\r\n";
print SOCKET "Content-Length: $length\r\n";
print SOCKET "\r\n";

print SOCKET "$post_mes\r\n";

みたいな感じでやってみたんですが駄目でした。
なんの反応もないみたいです。

なお、いたずら目的ではありません。Perlも自分のPCで動かしてます。
0703 02/07/09 00:23ID:???
>>702
犯罪の悪寒・・・
0704nobodyさん02/07/09 00:25ID:???
>>703に禿げ同
070570202/07/09 00:27ID:???
ひょっとして外部からPOSTしては駄目なのでしょうか?
すいません。よく知らなくて・・・
0706nobodyさん02/07/09 00:31ID:???
>>702
lwp 使った方が楽だと思われ。使えない環境?
070770202/07/09 00:39ID:???
>>706
lpwってのはよくわからないです・・・
環境はWinでPerl5です。
0708.02/07/09 00:41ID:???
掲示板荒氏用のスクリプトでも参考にしなさい。
0709.02/07/09 00:42ID:???
>>707
検索ぐらい汁。
もっとも、"lpw" ではないが。
071070202/07/09 00:45ID:???
>>708
dukeとか言うのですよね。探してみます
>>709
すいません。
lpwで検索してもよくわかんないと思ったらlwpだったんですね・・
0711nobodyさん02/07/09 01:01ID:???
何の反応も無いじゃ解らん
print while(<SOCK>);

ってして、どんなレスポンス帰って来てるのか読んでみ
071270202/07/09 04:02ID:???
教えて下さった方、ヒント下さった方、ありがとうございました。
なんとかPOSTできました。
0713nobodyさん02/07/09 04:31ID:???
>>698違う

ARGV = ARGuments Variable

だろ。

Value = 値
Variable = 変数

少しは勉強しろ
0714nobodyさん02/07/09 04:50ID:???
>>713
..... argument vector
071512102/07/09 21:35ID:7t2WvFst
ココ最高でした。サンプルとかタダだし、ネタとしては使えると思います。
ちなみに僕はロリです、同士な人はいってください。
http://muke.up.to
0716nobodyさん02/07/09 22:15ID:jsAirJtA
@data=(1,2,3,11,34)の様な配列が、あった場合
0〜99の数字で(1,2,3,11,34)を含まない、配列を得るにはどうしたら良いのでしょうか?
例えば、(4、5、12)
0717nobodyさん02/07/09 22:19ID:lugOGira
GETかPOSTかメソッドを判別し、
& と = をsplitして文字コードを変換したんですが、

local(@query) = split(/&/, $query);
foreach (@query) {
tr/+/ /;
($key, $val) = split(/=/);
$key =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge;
$val =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge;
$val =~ s/\r\n/\n/g;
$in{$key} = $val;
}

送られてくるデータの引数が複数ある場合は、このほかに
何かつけ加えなければならない?

0718nobodyさん02/07/09 22:22ID:???
local($pair,$buffer);
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
$buffer = $ENV{'QUERY_STRING'};
}
local(@pairs) = split(/&/,$buffer);
foreach $pair (@pairs) {
local($name,$value) = split(/=/,$pair);
$FORM{$name} = $value;
}
0719nobodyさん02/07/09 22:25ID:???
=~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1 )/eg;
0720nobodyさん02/07/09 22:34ID:???
>>716答え教えるの面白くないからヒントね


@data = (1, 2, 3, 11, 34);

for ( 0..99 )
{
 foreach ( @data )
 {
  push
 }
}
0721nobodyさん02/07/09 22:38ID:???
>>716
4, 5, 12を除いてみた.

%exclude = (4 => 1, 5 => 1, 12 => 1);
@data = grep { !$exclude{$_} } 0 .. 99;
072272102/07/09 22:39ID:???
>>720
スマソ…
0723nobodyさん02/07/09 22:40ID:lugOGira
> 719
それってどういうこと?
よくわかんない…、スマソ

0724nobodyさん02/07/09 22:45ID:???
=~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("c", hex($1))/ge;
より、
=~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1 )/eg;
の方が早いって言いたいんじゃない?
072571602/07/09 22:51ID:???
>>720
>>721
 こんなに、すぐレスくれるなんて思っていませんでした。
有り難う御座います。

これから、考えてみます。なにせ初心者な物でチンプンカンプンです。
0726ヽ(`Д´)ノ  ウワァァン02/07/09 23:29ID:gcNlx8b2
Win2000pro上でwwwサーバーを起動するところまではできたのに
CGIファイルをエクスプローラーで見ようとすると文字化け! ヽ(`Д´)ノ  ウワァァン
レンタルサーバー上にアップしたら文字化けしないのに! ヽ(`Д´)ノ  ウワァァン
0727nobodyさん02/07/09 23:45ID:???
>>726
print "Content-type: text/html; charset=Shift_JIS\n\n"; ヽ(´∀` )ノ
0728 02/07/10 00:48ID:Q4ccJnsM
パールって、
$a = 10;
だと
$a2 で 20 になるのですか?
0729 02/07/10 00:51ID:???
>>728
するどいな。だれにおそわった?
0730 .02/07/10 01:09ID:???
ソース見てたらなんとなくそう思ったのです。

本当なの?
$a2 って変数は使えないの?
0731nobodyさん02/07/10 01:13ID:fQbDc9qZ
パスワード入力みたいのでさ
入力した文字を****と表示して
さらにクッキーにも****と記録するにはどうすればいいの?

…別に使う訳じゃないんだけど興味。
0732nobodyさん02/07/10 01:13ID:???
$a + 2 足し算
$a - 2 引き算
$a * 2 掛け算
$a / 2 割り算
0733nobodyさん02/07/10 01:15ID:???
>>731
crypt関数で暗号化してから記録
0734nobodyさん02/07/10 01:15ID:fQbDc9qZ
>>733
さんきゅ。
後は調べる
0735nobodyさん02/07/10 06:44ID:???
おもったけどさ、削除パスを暗号化する前にいったん別ファイルに記録しとけばそいつがのホームページの掲示板の管理パスとかフリーメールにログインできたりするよな
0736由々しき問題でありぞっとしない02/07/10 07:10ID:???


http://www.google.com/search?num=100&hl=ja&ie=UTF-8&oe=utf-8&as_qdr=all&q=%E4%B8%AD%E5%AD%A6%E7%94%9F++%E5%9B%BD%E8%AA%9E%E5%8A%9B+%E4%BD%8E%E4%B8%8B+%E5%95%8F%E9%A1%8C&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
0737nobodyさん02/07/10 07:43ID:???
>>728
さんは凄腕になれますね、、
0738nobodyさん02/07/10 09:20ID:???
>735
全てのパスワードを同じ物にするようなマヌケな奴相手ならな。
まぁ、マヌケが多いのは確かだが。
0739nobodyさん02/07/10 09:41ID:???
>>738
ユーザは性アフォ説で接していかないと・・・。
0740nobodyさん02/07/10 10:21ID:9iF/zPMp
数字以外が入力されたらエラーメッセージを出したいのですが
うまくいきませんでした
どうすれば良いですか?

#入力されたのが数字かどうかチェック
if($P eq /[^0-9]/){print "数字を入力してください。";}
else{

if($P == /[^0-9]/){print "数字を入力してください。";}
else{

0741nobodyさん02/07/10 10:24ID:???
正規表現使うときは、

  =~ //

だろ。
074274002/07/10 14:18ID:lBfYsgML
>>714
できましたーーー!!
ありがとうございます
0743nobodyさん02/07/10 14:23ID:???
>>742
誰に御礼を言ってるんだか。
074474002/07/10 16:33ID:???
>>741さんでした(汗
ありがとうございます
0745nobodyさん02/07/10 16:58ID:???
(≧∇≦)
0746nobodyさん02/07/10 17:04ID:???
404とかのエラーコードを吐き出させるのってどうやるのですか?
074774602/07/10 17:14ID:???
あ、分かりました。
0748nobodyさん02/07/10 19:02ID:???
>>740
/[^0-9]/ → /^[0-9]+/
0749nobodyさん02/07/10 19:25ID:???
>748
それだと意味が変わるぞ。
>740の書き込みとif文の構成をよく見ろ。
0750nobodyさん02/07/10 19:28ID:???
>>748
それやるなら、
if ( $P !~ /^[0-9]+/ ) { }
か
unless ( $P =~ /^[0-9]+/ ) { }
じゃないと。
0751 ◆adminSE. 02/07/10 19:59ID:???
>>746

.htaacessでやるんじゃなかったっけ?

0752japh ◆J.5V8ta6 02/07/10 20:43ID:???
>>751
うわっ、何てカコイイトリップなんだ!
0753 ◆adminSE. 02/07/10 20:48ID:???
>>752

トリッパー使って3時間ほどadminで検索してたら偶然SE付きのがHITしますた
0754nobodyさん02/07/10 22:02ID:???
$fied[1]にはいってるすべての文字列【日本語含む】を@にしたいとき
$fied[1]=~tr/a-zA-Z_0-9\/.\n?-!"#$%&'()\=~|\{\`\+\*}_?><,\/\\\];@\[\\^-/@/cs;
↑このように書くしかないんですかね?
[a-zA-Z_0-9]以外の文字ぜんぶをあらわす特殊変数みたいなのありませんか。
■ このスレッドは過去ログ倉庫に格納されています