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

Perlコーディング初心者質問スレ Part 46

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/01/18(水) 02:17:46ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

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

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0550nobodyさん2006/02/09(木) 21:40:19ID:???
>>548
いやいや、文法上良いの。
0551nobodyさん2006/02/09(木) 21:56:50ID:???
>>549-550
0552nobodyさん2006/02/09(木) 21:58:17ID:???
アクセスした人の環境変数を全てtextに書いていくプログラムを書いたのですが、
 #!/usr/local/bin/perl
 
 print "Content-type: text/html\n\n";
 open(DATA, ">> data.dat");
 print(DATA "%ENV<HR>\n");
 close(DATA);
 exit;

エラーが出て動きません。
自分ではこのソースに間違いを見つけられないのですが、その他パーミッションなどの設定のほうを疑うべきでしょうか…?
お願いしますm(_ _)m
0553nobodyさん2006/02/09(木) 22:00:39ID:???
>>552
何でもカッコつけりゃいいってもんじゃないってこと。
0554nobodyさん2006/02/09(木) 22:02:20ID:???
どういうことですか…?
0555nobodyさん2006/02/09(木) 22:09:16ID:???
コンマが足りない
0556549=5502006/02/09(木) 22:16:00ID:???
>>551
ん?何かまずいこと言った?
らくだ本にも、
> 次のような記法 (中略) で使われる裸の識別子は、裸のワードとは見なされない。
> なぜなら、これらは「文法的にほかに解釈がない」のではなく、
> 規則によって陽に許される書き方だからである。
って書いてるよ。
0557nobodyさん2006/02/09(木) 22:19:08ID:???
はいはいわろすわろす
0558nobodyさん2006/02/09(木) 22:35:43ID:???
>>552
パーミッションじゃない?
open() のとこをこんな風にしてエラーメッセージを出させてみては?

unless (open(DATA, ">> data.dat")) {
print "Open error: $!\n";
exit;
}
0559nobodyさん2006/02/09(木) 23:12:20ID:???
>553
クイズにヒントを出して楽しむ場所じゃ有りません

>552
 print "Content-type: text/plain\n\n";
 open(DATA, ">>data.dat");
 print DATA "%ENV<HR>\n";
 close(DATA);
 print "output ok\n";
 exit;
0560nobodyさん2006/02/09(木) 23:17:44ID:???
>>559
0561nobodyさん2006/02/09(木) 23:21:13ID:???
>>560
0562nobodyさん2006/02/09(木) 23:21:28ID:???
はいはいわろすわろす
0563nobodyさん2006/02/09(木) 23:22:22ID:???
はいはいわろすわろす
0564nobodyさん2006/02/09(木) 23:26:16ID:???
はいはいわろすわろす
0565nobodyさん2006/02/09(木) 23:26:53ID:???
>562-564
0566nobodyさん2006/02/09(木) 23:26:57ID:???
webprog板らしい流れだな
0567nobodyさん2006/02/09(木) 23:28:12ID:???
>566
>565
0568nobodyさん2006/02/10(金) 00:21:11ID:???
わろわろはいすはいす
0569nobodyさん2006/02/10(金) 00:23:50ID:???
はいわろ
05705522006/02/10(金) 02:09:46ID:???
わかる人がいないようなので失礼しますね
0571nobodyさん2006/02/10(金) 02:17:10ID:???
my @tmp1 = ();
my %tmp2 = ('mode'=>'hoge','data'=>'test');
push @tmp1, \%tmp2;

↑と同じ事を1行でやろうとすには、どうしたら良いのでしょか?

my @tmp1 = (('mode'=>'hoge','data'=>'test'));

↑では、できませんでした…。
0572nobodyさん2006/02/10(金) 02:39:03ID:???
mixiのコードばら撒かれちゃったらしいけどどこかに残ってませんか?
0573nobodyさん2006/02/10(金) 02:44:06ID:???
home.plだけならある
0574ヽ(´ー`)ノ ◆.ogCuANUcE 2006/02/10(金) 03:17:56ID:???
>>571
my @tmp1 = ({'mode'=>'hoge','data'=>'test'});

リファレンスについて勉強しる。
0575nobodyさん2006/02/10(金) 04:19:33ID:???
>552=570
レスをちゃんと読んだか?
質問の投げ去りはやめろや
0576質問2006/02/10(金) 11:34:07ID:+Mjswkwe
2項分布の計算を行いたいのですが、
2項分布内のひとつの項を$k_posとする場合、

for($j=1;$j<10;$j++){
$k_pos=combi($g,$b)*(($bl_bun[$j]/65536)**$b)
*(((65536-$bl_bun[$j])/65536)**($g-$b));
}

というコードにすると、$gや$bが大きい場合、結果が出なくなってしまいます。
(combiというのは自作subです)
恐らく、掛け合わせる数が思いっきりでかい数と思いっきり小さい数を掛け合わせてるのが原因だと思います。
何か解決方法はありますでしょうか?よろしくお願いします。
0577nobodyさん2006/02/10(金) 14:05:43ID:???
use bignum;
は試してみた?
0578nobodyさん2006/02/10(金) 17:20:13ID:???
Content-Lengthに手こずっています。
これの値がいい加減だと読み込みが変になるみたいで、レスポンスが大幅に遅くなりました。
i-modeのためContent-Lengthは必須みたいで困ってます。

値を取るのは一般的な方法で全データを変数に入れてlengthで計ってるんですけど
うまくいかないです。
何が原因やら・・・文字コードはUTF8で統一していますが・・・
0579nobodyさん2006/02/10(金) 17:21:22ID:???
>>1
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
05805782006/02/10(金) 17:40:28ID:???
ギャハ。自己解決しました。
どうも。でへへ。
もしかしたら僕と同じミスをする人が出てくるかもしれないので原因を書いておきます。

えーと、lengthで計算する変数に"Content-type: text/html"を含めていたので
うまく計算できなかったみたいです。
この一文を外して、
print "Content-type: text/html\n";
print 'Content-Length: ', $length, "\n\n";
print $data;
としたら上手くいきました。
どうもスレ汚しすみません。
0581nobodyさん2006/02/10(金) 20:19:09ID:???
ズコー!
0582nobodyさん2006/02/10(金) 21:02:02ID:???
100%同じミスするようなのはいない
0583nobodyさん2006/02/10(金) 21:15:50ID:???
すまん、同じミスをしてた奴を見たことある。
0584nobodyさん2006/02/10(金) 21:48:34ID:???
ワラタ
0585nobodyさん2006/02/10(金) 21:59:59ID:???
ごめん、一度だけ同じミスやった
0586nobodyさん2006/02/10(金) 22:29:59ID:???
>>580
これを機にHTTPの仕様を勉強するといいかも寝
0587nobodyさん2006/02/11(土) 00:14:36ID:???
>586
おやすみうな
0588nobodyさん2006/02/11(土) 01:25:48ID:???
おやすみ
0589質問2006/02/11(土) 08:21:02ID:qlKqkAMK
use bignum
したいのですが、bignumはどこにあるのでしょうか?
0590nobodyさん2006/02/11(土) 09:05:06ID:???
print join("\n", @INC);
0591nobodyさん2006/02/11(土) 11:30:25ID:???
>>589
5.8以降なら標準なんだけど、また5.6とか?
0592ヽ(´ー`)ノ ◆.ogCuANUcE 2006/02/11(土) 13:32:23ID:???
perldoc -ml bignum
0593nobodyさん2006/02/11(土) 13:49:55ID:???
>>592
5.6.1 以下だと「only one of -t, -u, -m or -l ...」と叱られるな。
0594ヽ(´ー`)ノ ◆.ogCuANUcE 2006/02/11(土) 18:51:50ID:???
>>593
あ、なるほど。そうすると不完全だけど、perldoc -l かな。

ttp://blog.livedoor.jp/nipotan/archives/50146747.html
0595nobodyさん2006/02/12(日) 06:58:32ID:bHuVlhbg
perlで乱数を求める時にrand関数を使いますけど、
バージョンが5.0?(詳しくは失念しましたが)からは種となるsrandを使わなくても良くなりましたよね?

バージョンが5.8のサーバで昔作られたsrandが使用されているスクリプトを使っていたんですが、
先日新しいバージョンではsrandを使うとむしろ乱数の品質が下がると言う事を知りました。

元よりどうも乱数が偏っているなと感じていたんですが、
それはこのsrandの性と考えていいんでしょうか?
それとも単なる勘違い的なものでしょうか?

乱数の使い方はおみくじとかサイコロとかそういったもので、
何かのシミュレートとかの用途ではありません。

今までサイコロで言えば1が5回連続して出たけど、それは確かにたまにはあるし、
たまたま出た時が強く印象に残っただけだ、と思っていたんですが。

とりあえずsrandは外す方向で考えているのは当然なんですけど、
どうにも今まで起きてた事象のモヤモヤが引っかかって。
0596nobodyさん2006/02/12(日) 08:04:29ID:???
srandってのは、使う乱数表を決めるようなもの。
srand(1)なら1番の乱数表を使うというような。
乱数の質はシステム依存。

1万回サイコロを振った程度なら偏るものだけどね。
偏りがほしくないのなら、別の方法を考える。
0597nobodyさん2006/02/12(日) 09:33:07ID:???
> 1万回サイコロを振った程度なら偏るものだけどね。
> 偏りがほしくないのなら、別の方法を考える。

? 何を言っているのかわかってる?
0598nobodyさん2006/02/12(日) 09:56:51ID:???
ウホッ良い勘違い!
0599nobodyさん2006/02/12(日) 10:05:55ID:???
おみくじやさいころではどっち使っても人間が直接体験できるような偏りは出てきません。
ただの勘違い。

ただしまともな乱数使ってもプログラムの中で偏った分布をするような
プログラミングがされていたら当然偏るけどね。
06005962006/02/12(日) 10:07:07ID:???
>>597
それでは、確率と乱数とばらつきについて教示ください。
数学については、なにぶん素人なので。
06015962006/02/12(日) 10:10:06ID:???
サイコロ一万回程度ではばらつきが大きくて、偏りが出るということなんだけど。
0602nobodyさん2006/02/12(日) 11:07:16ID:???
質問です、
表示させるすべての桁でランダムで数字を表示するプログラムを改造して、アルファベットもランダムで表示させたいのですが、どう改造すればいいでしょうか?


ソースは、
# ランダム桁のランダム数字の生成
$max_num =1;
$min_num =1;
for( ; ; ){
$num_digit = rand($MAX_DIGIT)%$MAX_DIGIT+1;
last if($num_digit >= $MIN_DIGIT);
}
for($i=0; $i<$num_digit; $i++){ $max_num *= 10; }
$min_num = $max_num/10;
for( ; ; ){
$num = rand($max_num)%$max_num;
last if($num >= $min_num);
}

です。

0〜9まではこれで表示できるんですが、'a'〜'z'までを時間を種にして表示させたいんです。
0603nobodyさん2006/02/12(日) 13:32:27ID:???
@atoz = (a..z);
0604nobodyさん2006/02/12(日) 14:11:18ID:???
文字列の中から、「XXX号室」 の部分を抜き取ろうとしていますが、文字化けが起きて困っています。
XXX には半角アルファベット大文字か数字が入り、1桁から3桁程度です。
だいたいうまくいくのですが、「階」という漢字のあとにXXX号室が来ると化けてしまいます。

ソースコードは次の通りです。環境はWindows2000 ActivePerl5.8.7です。
my @a;
my @b;
push @a, "A4号室";#うまくいきます
push @a, "1FC5号室";#うまくいきます
push @a, "1階206号室";# K206号室 になってしまいます
push @a, "A棟207号室";#うまくいきます
foreach (@a){
push @b, "$&\n" if /[A-Z0-9]+号室/;
}
print @b;

「1階206号室」のときだけ「K206号室」になってしまいます。
何が原因で、どうすればよいのでしょうか。
どなたかご教授いただけると助かります。
0605nobodyさん2006/02/12(日) 14:38:27ID:???
>>604
「階」が Shift_JIS だと「8A 4B」なので二バイト目の「4B」が「K」にあたるのが原因だね。
/[A-Z0-9]+号室/s にすればいい。
06066052006/02/12(日) 14:39:03ID:???
ごめん、 Ruby と勘違いした。
Perl だとどうするんだろう?
0607nobodyさん2006/02/12(日) 14:44:47ID:???
/(?<![\x81-\xfc])[A-Z0-9]+号室/

てけとーな応急処置だけど、よかったらどうぞ。
0608nobodyさん2006/02/12(日) 14:46:18ID:???
シングルクオートと、quotemetaを試すがよろし。
0609nobodyさん2006/02/12(日) 14:50:41ID:???
>>608
すぐに気付くとは思うけど、今回のケースではそれじゃダメよん。
06106042006/02/12(日) 15:14:54ID:???
早速のレスありがとうございます。
原因は>>605さんのおっしゃるように、Shift_JISの2バイト目とマッチしてしまったからなのですね。
勉強になりました。
対処としては>>607でうまくいきました。ありがとうございました。

(?<![\x81-\xfc])の部分ですが、Shift_JISの2バイト目を取らないように、
「左側にShift_JISの1バイト目が存在しない位置」を指定しているという理解で合ってますか?
06116042006/02/12(日) 15:48:35ID:???
すみません、さっきの方法ではうまくいかない場合がありました。
>>604のコードには記述しませんでしたが、処理対象には●12号室 ■10号室 のようなパターンもあり、
これまでは上手くいってましたが、>>607では 2号室 0号室 と出力されてしまいます。
Shift_JISは使わないほうが良いのでしょうか・・・
0612nobodyさん2006/02/12(日) 15:59:29ID:???
そうだよ
0613nobodyさん2006/02/12(日) 16:57:35ID:???
んなら、ユニコードでも使ってみようか。

use Encode;

my $pattern = '([A-Z0-9]+号室)';
my $str = "1階206号室";
Encode::from_to($pattern, 'sjis', 'utf8');
Encode::from_to($str, 'sjis', 'utf8');
$str =~ /$pattern/;
my $match = $1;
Encode::from_to($match, 'utf8', 'sjis');
print $match;
06146072006/02/12(日) 18:51:15ID:???
ほんじゃぼくはアドホックに正規表現をいじる係ね。
あくまで >>613 の言うように utf8 で処理するのが王道なのは百も承知で。

push @b, "$1\n" if /(?:[\x81-\xfc].)*([A-Z0-9]+号室)/;
0615nobodyさん2006/02/12(日) 20:04:49ID:???
>600
乱数以外の偏らない別の方法って何?
ヒントだけでもいいから教えて

偏らないってどういう意味?
1万回やると「6」は1666回出るの?それとも1667回出るの?
0616 ◆TWARamEjuA 2006/02/12(日) 20:07:39ID:???
/[A-Z0-9]{1,3}号室/
0617nobodyさん2006/02/12(日) 20:09:39ID:???
/[A-Z0-9]{1,3}号室/i
または
/[A-Za-z0-9]{1,3}号室/
06186072006/02/12(日) 20:43:14ID:???
>>616-617
それだと、

>push @a, "1FC5号室";#うまくいきます

などで残念なことに。
0619nobodyさん2006/02/12(日) 23:28:00ID:ptODJMag
削除パスワード機能のついた掲示板を設置しているんですが
削除パスワードが“1111”や“1212”、“1122”みたいな単純なパスワードを弾くには
どうすればいいでしょうか?

if ($password = ~ /1111/){ $error = 'エラーです'};
if ($password = ~ /1212/){ $error = 'エラーです'};

みたいにいちいち指定するよりもスマートな方法を伝授してください


0620nobodyさん2006/02/12(日) 23:31:23ID:???
"単純"の定義が・・・
06216192006/02/12(日) 23:42:10ID:ptODJMag
削除パスワードは4桁の英数字にしてあるので
1111 などの連続
1212 1122 1222 などの2つの種類の文字のみ

のつもりです
06226042006/02/12(日) 23:54:16ID:???
>>613
うまくいきました。ありがとうございます。
調べて初めて知ったのですが、UTF8だと文字の途中のバイトでマッチしなくてすむようなので、
このやり方が適切みたいですね。

>>614
[\x81-\xfc]のあとのドットで2バイト目をマッチさせてるんですね。
ドットは任意の1文字としか考えてませんでしたので、途中の1バイトを1文字とみなして
マッチさせるとは思いもしませんでした。勉強になります。

>>616-617
そのやり方でも上記データを処理できますが、アルファベットは大文字固定で、
長さは3文字以上もありうるので[A-Z0-9]+になります。レスありがとうございました。
0623nobodyさん2006/02/12(日) 23:57:14ID:???
my %seen;
if (scalar (grep { !$seen{$_}++ } split //, $password) <= 2) {}

とかどうだろう。
06246192006/02/13(月) 00:18:53ID:NkDDMowL
>>623
どうもです

書き忘れましたけど最初↓
if ($password = ~ /(.)(\1|(.))(\1|\2)(\1|\2)/){ $error = 'エラーです'};

これだとなんかおかしいんです
どこがおかしいのか自分でも
0625nobodyさん2006/02/13(月) 01:06:45ID:???
3桁程度って言ってるからわざわざ3桁までにしたのにorz
0626nobodyさん2006/02/13(月) 01:07:12ID:bzAWjmTk
WindowsのApacheで自宅サーバを立てました(ActivePerl)

プログラム中に
print $env = $ENV{'QUERY_STRING'};
と文を書き
$envに「name=maruyama」が入ることを期待して

URLに
http://www.hogehoge.jp/cgi-bin/index.cgi?name=maruyama
を打ち込みましたが「Internal Server Error」となります。

この場合URLの「?」の後ろ(name=maruyama)をブラウザに表示させるにはどのようにしたらよいのでしょうか?
0627nobodyさん2006/02/13(月) 01:11:46ID:???
my($query) = $ENV{'QUERY_STRING'} || "";
print $query;
0628nobodyさん2006/02/13(月) 01:12:32ID:???
あっ、こんてんとたいぷ はちゃんと書いてね
0629nobodyさん2006/02/13(月) 01:14:48ID:???
HelloWorld!から初めて欲しいね。
06306192006/02/13(月) 01:23:47ID:NkDDMowL
>>624をお願いします

if ($password = ~ /(.)(\1|(.))(\1|\2)(\1|\2)/){ $error = 'エラーです'};
0631nobodyさん2006/02/13(月) 01:33:47ID:???
>630
最後の2文字を入れ替えてごらん

それと・・・
>629
0632nobodyさん2006/02/13(月) 01:37:18ID:bzAWjmTk
>>627
違うところが間違ってました。
お答えありがとうございました。

自己解決しました。
ご迷惑をおかけしました
06336192006/02/13(月) 01:38:58ID:NkDDMowL
>>631
if ($password = ~ /(.)(\1|(.))(\1|\2)(\1|\2)/){ $error = 'エラーです'};
でも
if ($password = ~ /(.)(\1|(.))(\1|\2)(\1|\2)/){ $error = 'エラーです';}
でも結果は同じでした


(.)(\1|(.))(\1|\2)(\1|\2) ←ここをどうすればいいんでしょうか?
0634nobodyさん2006/02/13(月) 02:17:57ID:???
>621

# 9文字以下はエラー
if(length($pass) < 9){ &error(); }
# 数字小文字大文字記号が混ざってないとエラー
if(!(($pass =~ /\d/) && ($pass =~ /[a-zA-Z]/) && ($pass =~ /[_!#$%&'()=\-"\[\]\|{}\/\.,\?]/))){ &error(); }
# 同じ文字が連続したらエラー
if($pass =~ /([0-9a-zA-Z])\1/g){ &error(); }
06356342006/02/13(月) 02:20:28ID:???
最後の行修正
$pass =~ /(.)\1/g
06366192006/02/13(月) 02:25:30ID:NkDDMowL
>>635
どうもです。

2種の文字で構成されるパスの場合のエラーの場合どうすればいいでしょうか?
0637nobodyさん2006/02/13(月) 02:28:03ID:???
お前ら釣られすぎ
0638nobodyさん2006/02/13(月) 02:49:38ID:???
>>623でいーんじゃないの?
0639nobodyさん2006/02/13(月) 02:54:32ID:???
>>625
それでも "1階23号室" が "K23号室" になっちゃってダメじゃね?
06406342006/02/13(月) 04:00:03ID:???
>636
ちったぁ考えろ
終了
06416192006/02/13(月) 04:12:30ID:???
>>640
正規表現の勉強し直せ
06426192006/02/13(月) 04:54:25ID:???
>>641
私も頑張るからさ
0643nobodyさん2006/02/13(月) 14:25:40ID:???
ある入門書には、
open(UNKO "kusai.txt");
@BENKI=<UNKO>;
みたいにopen()関数で開いたテキスト内容(別にテキストじゃなくても良いが)
を配列に代入してるけど、スカラーじゃ駄目なの?
スカラーだと変数が32bitしかないから、エラい人が個々の配列にに自動で文字列を
一文字づつ代入してくれるから?
06446432006/02/13(月) 14:26:52ID:???
ごめん、日本語になってない ○rz
脳内補正よろしく。
0645nobodyさん2006/02/13(月) 14:56:24ID:???
>>643
<>はスカラーコンテキストで使用すると一行読み込む。( $hoge = <FUGA> )
リストコンテキストで使用するとファイルをすべて読み込む。( @hoge = <FUGA> )
一気に配列に読み込む必要性が無ければ、
スカラーコンテキストで一行ずつ読み込んだ方が使うメモリーは少なくてすむので
私としてはそうすることをお勧めしたい。
しかし、一気に読み込むことでファイルをロックするべき時間が短くなるという利点もあり、
そういう風に一気に読み込むことを好む人もいる。前にこのスレで議論になったこともあった希ガス。

> 個々の配列にに自動で文字列を一文字づつ代入
配列の個々の要素に一文字一文字、ということ?一行ずつの文字列が入るよ。
$hoge[0] = "foo\n";
$hoge[1] = "bar\n";

> スカラーだと変数が32bitしかないから
Perlでは内部的に自動で整数型、不動小数点型、文字列型などを変換する。
ユーザ側は通常大きさを考えるようなことは無いし、この場合では文字列型になる。
0646nobodyさん2006/02/13(月) 18:09:49ID:???
>644
# メモリの許す限り全Read
@lines = <IN>;

# 改行まで
$line = <IN>;

メモリ使用量に関して645さんのを補完すると
foreach (<IN>){ 〜処理〜 }
じゃなくて
while (<IN>){ 〜処理〜 }
です。


・・・だよね? (;´∀`)
0647nobodyさん2006/02/13(月) 20:42:55ID:???
数字だけのを弾くとかすれば?どこらへんまで弾きたいのか分からないから何とも言えない
0648nobodyさん2006/02/13(月) 22:21:17ID:???
画面をFRAMEで縦に2分割してデータの読み書きのプログラム作ってます。
上のaaa.cgiはフォーム入力からデータをファイルに書き出すCGIです。
SUBMITで自分自身を呼び出して何回も書き込めるようにしています。
下のbbb.cgiはaaa.cgiで作ったファイルからデータを1件づつ読み込んでいます。
【疑問】aaa.cgiでSUBMITを押してもbbb.cgiが動かないので画面のデータが更新されない。
【希望】aaa.cgiで更新したデータをすぐに下のbbb.cgiを動かして画面を更新したい。
    bbb.cgiに更新ボタンを設置するのはやりたくない。

どうすればいいでしょうか?
0649nobodyさん2006/02/13(月) 22:38:17ID:???
チャット用のcgiをどっかから拾ってきて設置する。
■ このスレッドは過去ログ倉庫に格納されています