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

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

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

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

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

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

過去ログやお勧めサイトは >>2-10
0756nobodyさん05/03/01 03:14:15ID:???
いや俺。
0757nobodyさん05/03/01 03:42:42ID:???
>>755
split '*',$value;
こうするとエラーになります。理由は*が正規表現のメタ文字だからです。
しかしシングルクォートなのに展開されるのはこまります。

split '\*',$value;
split /\*/,$value;

こういうことはしたくありません。何とかできませんか?
0758nobodyさん05/03/01 04:18:59ID:???
>>757
逝ってる意味がわかりません!
0759nobodyさん05/03/01 04:28:19ID:???
>>757
split quotemeta '*', $value;
0760nobodyさん05/03/01 04:47:02ID:???
>>758
長いんですが・・・・
エスケープしたくないのは一文字分うっとおしいからです。
quotemetaだともっと長くなってしまいますよねorz

でもこんな夜中に親切にありがとうござまいしたm(_ _)m
0761nobodyさん05/03/01 05:34:57ID:???
>>760
自分専用のライブラリでも作ったら?

sub sp($$){
my $reg_str = shift;
my $in_str = shift;

split quotemeta $reg_str, $in_str;
}


とか作っておけばそれ以後は

sp '*', $value;

とかできるじゃん。



0762nobodyさん05/03/01 07:48:10ID:???
>>757
> split '[*]',$value;
0763nobodyさん05/03/01 09:51:40ID:???
>>760
一文字分長いからって・・・('A`)
0764nobodyさん05/03/01 12:18:28ID:VBiT7+i4
hoge.cgiにアクセスしたらリダイレクトでhoge2.cgiにLocationで飛ばしたいのですが、
その時にPOSTメソッドでfoo=barなどの情報も送りたいと思っています。

ヘッダー情報はどのように出力させたらよいでしょうか?
0765nobodyさん05/03/01 12:20:59ID:???
>>764
POSTじゃ無理だから普通はGETでURLに埋め込む
どうしてもPOSTにこだわるなら.htaccessでmod_rewrite使う
0766nobodyさん05/03/01 12:38:51ID:VBiT7+i4
>>765
THX!
無理なんですか。
ありがとうございました。
0767nobodyさん05/03/01 13:37:54ID:???
defined $ENV{'REMOTE_ADDR'} && $ENV{'REMOTE_ADDR'} ne '127.0.0.1'
これを条件文にして真なら
open MAIL,"| /usr/sbin/sendmail -t";
もしも偽なら
open MAIL,">mailtest.txt";
これを実行してその後は同じことをしたいのです。
print MAIL "To:\n";
print MAIL 'From: ',"\n";
print MAIL '";
print MAIL $mail;
close MAIL;

どうすればいいでしょうか?ifはダサイので嫌いです。
?演算子でいきなりやれますか?
0768nobodyさん05/03/01 13:39:45ID:???
勘違いします。

そうではなくて"| /usr/sbin/sendmail -t"これと">mailtest.txt";これの
どちらかを変数に入るようにして
open MAIL,$type;
などとしても動作するのですか?
0769nobodyさん05/03/01 13:48:56ID:???
素直にif-else使え
ダサいとか思ってるのはお前だけだから
あと日本語の勉強頼む
077076705/03/01 14:08:26ID:???
>>769
どういう意味でしょうか?
ダサイと思ってるのが自分だけだとしてそれが一体何の関係があるのですか?
右倣えしてれば満足できちゃう方ですか?
0771nobodyさん05/03/01 15:09:18ID:???
>>767
open MAIL, defined $ENV{'REMOTE_ADDR'} && $ENV{'REMOTE_ADDR'} ne '127.0.0.1'
 ? "| /usr/sbin/sendmail -t" : ">mailtest.txt";
ということ?
0772nobodyさん05/03/01 16:02:49ID:???
一文字分長いとかif分ダサいとか笑える
0773nobodyさん05/03/01 16:26:39ID:???
答えたくない質問はスルーでお願い。
いちいち言わせないでね。
077476705/03/01 16:55:23ID:???
>>771
もういいです。もっと綺麗に済ませました。ごめんなさい。
>>772
画面の前で一人で笑うんだね君は。
>>773
基本的に今回は私が八つ当たりをしただけなのでごめんなさい。
0775nobodyさん05/03/01 16:57:23ID:???
ベンチ取ると微妙にif-elseよりも三項演算子のほうが速い罠。
0776nobodyさん05/03/01 17:01:59ID:???
if(1){
  print <<"EOM";
そのとき
妹は
EOM
}
だとインデント無視しなければいけないのでいつも
if(1){
  print "そのとき\n";
  print "妹は\n";
}
と記述していますがこれだと面倒+速度遅くなってしまいます。
美しくかつ簡単で記述する方法はないでしょうか?
0777nobodyさん05/03/01 17:05:51ID:???
>>774
どうやったの?
0778nobodyさん05/03/01 17:16:19ID:???
>>776
ヒアドキュメントをネストすればいけるんじゃないか?
昔に誰かが言ってた。過去ログ読むか賢い人を待ちなさい。
0779nobodyさん05/03/01 18:08:05ID:AybE+O5L
出力について質問です。
print分は全て以下のような形式で書いています。

print $handle qq("テスト");

これで、$handle="FH";とするか$handle="STDOUT";とするかでファイルに落としたり
画面にそのまま出力したり振り分けているのですが、
同一処理を画面に出しながらファイルに保存するにはどうしたらいいのでしょうか?
0780nobodyさん05/03/01 18:16:06ID:???
>>779
普通は出力なんて1回。だから出力内容をファイルにも入れたいなら

print $source;
open FH,">test.txt";
flock FH,2;
print FH $source;
close FH;

でおわる。

まずは出力はルーチンに投げておしまいというわかりやすいプログラミングを心がけてはいかが?
0781nobodyさん05/03/01 18:18:58ID:???
>>708,767
上のガキはスルーで。
0782nobodyさん05/03/01 18:22:57ID:???
tee にパイプで送るとか > 画面とファイルの両方に出力
0783nobodyさん05/03/01 18:28:20ID:???
>>779
IO::Tee - Multiplex output to multiple output handles
http://search.cpan.org/~kenshan/IO-Tee-0.64/
0784nobodyさん05/03/01 18:38:52ID:???
>>776
Perlクックブックにレシピ1.11「ヒアドキュメントをインデントする」てのがある。
オレのもってるのは一つ前の版だが最新版でもどっかにあるだろう。

要約すると、「インデントつけといて自分で削れ」ってことみたいだな。
単に行頭の空白を全部削るやつとか、行頭の共通文字列を削る奴とか
いくつかの例がある。

0785nobodyさん05/03/01 19:35:54ID:???
>>776
つまりこういうことやね!

if(1){
  print do{(local$_=<<"  EOM")=~s/^  //mg;$_};
  そのとき
  妹は
  EOM
}
078674305/03/01 19:47:30ID:???
>>748
SJIS使ってて全角文字だったら文字の相性によってエラーが起きるの。
カッコつかうなら ( ) と < > 以外はこの問題が発生する可能性がある。
< > はタグで使うことが多くて見にくくなるから、普段は ( ) を使うんだけど、
その中にカッコを使いたいなら \) とかやらないで、 print qq!)! ってやってる、って意味。
! もこんな問題はおきません。
0787nobodyさん05/03/01 20:11:50ID:???
>>776
if(1){
    print fix(<<"    EOM");
        そのとき
        妹は
    EOM
}

sub fix
{
    (my $str = shift) =~ s/^\s+//gm;
    return $str;
}

Perlクックブック1.11
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq4.html#Why_don_t_my_E_lt_E_lt_HERE_docu

二行程度なら、私はこうするかな。

if(1){
    print "そのとき\n",
        "妹は\n";
}
0788nobodyさん05/03/01 20:29:30ID:3fkZkmcb
>>776
if(1){
print &fix;
}

sub fix {
return <<"EOF";
そのとき
妹は
EOM
}
0789nobodyさん05/03/01 20:35:33ID:p/vg3iSU
my @messages = qw(
  その時
  私は
);
print join("\n", @messages);

空白があるとダメだけど。
0790nobodyさん05/03/01 21:37:00ID:???
>>776
#思いきってこんなんどう?

(my$script=<<'EOM')=~s/(?:^|\?>\n?)(.*?)(?:<\?|$)/;print'$1';/sg;eval$script;
そのとき
妹は
EOM

#こんなこともできるよ!

(my$script=<<'EOM')=~s/(?:^|\?>\n?)(.*?)(?:<\?|$)/;print'$1';/sg;eval$script;
<?

for(1..10){

?>
[<? print $_ ?>]<br>
<?

}

?>
EOM

#PHPとかJSPとかASPが嫌いだったら推めないけど
0791nobodyさん05/03/02 11:01:25ID:???
>776
美しくもないしかなりの力技で処理的にも問題ありだと思うけど、
とにかくインデントしてソースの見た目をどうにかしたいってなら

if (1) {
$string = <<" EOF";
その時
妹は
EOF
$string =~ s/\t//g;
print $string;
}

↑インデントはTABでやってる場合ね
書き込みにTAB使えないから上のはスペースでインデントしてるけど
0792nobodyさん05/03/02 11:01:57ID:fmkJJ4kU
ファイルの読み込み&書き込みについて
読み込むファイルの中身
--------
1
data
--------
やりたいこと=最初の数字を抜き出して、数字を足して、データを上書き
つまりこんな感じに
--------
2
data
data
--------
書いてみたもの(失敗)
--------
open (IN, "$outputFILE");
@tes = <IN>;
close (IN);

$tes = $tes[0];
$tes++;
$tes[0] = $tes;

open (OUT, ">$outputFILE");
print @tes;
close (OUT);

open (OUT, ">>$outputFILE");
print OUT "data\n";
close (OUT);
--------
アドバイスおねがいします!!!
079379205/03/02 11:17:07ID:???
>>792
$outputFILE = "data.txt";
です
0794nobodyさん05/03/02 11:29:16ID:???
print @tes;

print OUT @tes;
0795792 05/03/02 11:59:36ID:???
>>794
うわあー
ありがとうございます!
はずかしぃ
0796nobodyさん05/03/02 14:24:28ID:???
まずはじめにヒアドキュメントなんてつかうなよ・。
0797nobodyさん05/03/02 17:03:02ID:???
>>796意味がわかりません
0798nobodyさん05/03/02 17:06:17ID:???
>>797
ショボ
0799nobodyさん05/03/02 17:19:36ID:???
だって初心者だもん
0800nobodyさん05/03/02 17:28:30ID:jdtsRVWh
すみません、Perl初心者です。
外部ドメインにあるXMLを読み込んできて、そのまま吐き出す方法は
ございますでしょうか?
どなたかご教授お願いいたします。
0801nobodyさん05/03/02 17:31:34ID:???
質問〜
スクリプトのトークンがほしいんだけど、
どうすりゃええのですか?

こーゆー時って、全部自分で作るの?
なんかモジュールないのかな?
記述渡したらリストになって返って来るヤツとか。
080280005/03/02 18:26:02ID:jdtsRVWh
解決いたしました。お騒がせいたしました。
0803nobodyさん05/03/02 18:30:33ID:???
このスレ見ながら勉強してたんですが、
これ>>648,649,652 はどうして
マッチした行頭...の下の本文の行も出力されるのですか?
080480305/03/02 18:31:55ID:???
これというのは、>>652のプログラムです。
0805leaf.child05/03/02 18:38:44ID:???
このように"Content-Type: text/plain; charset=iso-2022-jp\n\n"で日本語の文字化けを防ごうとしています。
メールは問題なく送れるのですが、"Content-Type: text/plain; charset=iso-2022-jp”
部分が本文に表示されてしまいます。

open(MAIL,"| $sendmail -t") || die ("Fail to send E-mail: $!");
print MAIL "To: $headerTo\n";
print MAIL "From: $headerFrom\n";
print MAIL "Subject: $headerSubject\n";
print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n\n";
print MAIL $body;
close(MAIL);

誰かわかる人いませんかぁ??
0806nobodyさん05/03/02 19:22:26ID:???
>>805
いちばんありがちなのは、$headerSubjectの最後に改行が含まれている、
だが。

こういう問題が出たときは、パイプじゃなくてファイルに書き出すように
して出力をよく眺めるとかするのが正攻法だな。



0807nobodyさん05/03/02 19:51:55ID:???
>>803-804
|| && or and
これらの演算子は短絡演算子って言って、演算子の左辺の結果が満たされた場合右辺は実行されないんよ。
つまり、行頭が ... で始まる行は、左辺の結果が真になるから右辺が実行されて $sample が含まれているかチェックされる。
含まれていたら、$target がセットされて、含まれていなければ $target がリセットされる。
行頭が、 ... で始まっていない行は、左辺の結果が偽になるから、右辺が実行されない。
だから、 $target の内容は、 ... で始まる行の結果に依存されて出力されるというわけ。
0808nobodyさん05/03/02 21:11:22ID:???
>>807
アホかこいつ?
0809leaf.child05/03/03 02:20:05ID:QkSLneVb
>>806
ありがとうございました。
Subjectの改行を直したところ
問題点は表示されなくなりました
0810nobodyさん05/03/03 07:35:14ID:???
>>807さんの説明で間に合っていると思うけど、少し補足。

$targetの役割は、プリントするかどうかの状態を記憶することで、一般的にフラグと呼ばれている。
これが真であるうちは、プリントされる。
これが変更されるのは/^\.{3}/にマッチしたときのみなので、
次に...で始まる行までプリントされる仕組み。
081180305/03/03 10:10:52ID:???
>>807,810
遅くなりましたが、
詳しい説明本当にありがとうございましたm(__)m
たいへん勉強になりました。
0812nobodyさん05/03/03 10:25:21ID:???
誰も
and &&
には突っ込まないんだな
0813nobodyさん05/03/03 10:56:31ID:???
え、なんで
0814nobodyさん05/03/03 11:14:57ID:???
>演算子の左辺の結果が満たされた場合右辺は実行されない
ここでしょう。
0815nobodyさん05/03/03 12:18:45ID:???
'||', 'or' の左辺が真を満たしたら右辺は実行されないし
'&&', 'and' の左辺が偽を満たしたら右辺は実行されないけどそれが変なの?
0816nobodyさん05/03/03 12:24:48ID:???
>真を満たしたら
>偽を満たしたら
そんなアクロバットな説明しなくていいですからwwwww
0817nobodyさん05/03/03 12:28:35ID:???
ごめん、なにがおかしいか正直わからん、教えて。
0818nobodyさん05/03/03 12:38:12ID:???
普通、「(条件を)満たす」というのは、真になることを言うからでしょう。
0819nobodyさん05/03/03 12:44:30ID:???
あ〜日本語の使い方がおかしいっていう話しね。
ありがとう、了解!
0820nobodyさん05/03/03 12:50:57ID:???
でも昔のバージョンだと shortcut されなかった罠。
082182005/03/03 12:51:29ID:???
あ、すまん、 PHP スレと間違えた。
0822nobodyさん05/03/03 13:01:21ID:???
環境euc
my $value =qq(あいうえお);
$valueの中に入ってるひらがなを半角カタカナにjcode.plを使用して変えたい。

jcode::tr(\$value,"あ-ん","ア-ン");
こうするとおかしなことになりますがどうしてですか?
jcode::tr(\$value,"あ-ん","ア-ン");
jcode::z2h_euc(\$value);
これだと今のところ大丈夫です。

やはり直接半角に変換は不可能ですか?しかし・・・内部的な処理は同じではないのか・
0823nobodyさん05/03/03 13:10:44ID:???
>>819
こいつアホ?
0824nobodyさん05/03/03 13:15:23ID:???
>>822
全角ひらがなと半角カタカナのコードの並び順が違うから。
全角ひらがなと半角カタカナは同じ。

まず文字コードとキャラクタセットについて勉強しましょう。
0825nobodyさん05/03/03 13:16:06ID:???
>>824 修正です。
>全角ひらがなと半角カタカナのコードの並び順が違うから。
>全角ひらがなと*全角*カタカナは同じ。
0826nobodyさん05/03/03 17:25:13ID:???
初心者丸出しの質問です
ファイルハンドルから1行ずつ読み取るときに
while (<IN>) {
chomp }
while ( chomp( $hoge=<IN>) ) { 〜 }
0827nobodyさん05/03/03 17:28:42ID:???
送信しちゃったorz
FHから1行ずつ読み込んでchompするときは
while (<IN>) {
 chomp
}
とか
while ( chomp( $hoge=<IN>) ) {
 〜
}
な感じでやってるんですが
デフォルト変数$_の時
こんな感じに1度で済ますことは出来ないのですか?
while ( chomp <IN> ) {
 〜
}
0828nobodyさん05/03/03 17:42:29ID:F2b+bV+t
@_ = <IN>;
chomp @_;
$_ = join ('',@_);
0829nobodyさん05/03/03 17:46:08ID:???
>>827
二番目のやつ、最後の行に改行が付いてない場合にマズイ気がする。
0830nobodyさん05/03/03 18:01:27ID:???
日本語が含まれてる文字列(EUC)でsubstr的な事するにはどう書いたらいいんでしょうか?
083182705/03/03 18:32:46ID:???
レスありがとうございます

>>828は一度に@_に入れてるんですよね?
使い所によっては便利ですね。勉強になります。

>>829
改行が無い場合は何もしないんじゃなくて0を返してたんですね
改行が無い場合は何もしないと間違って憶えてました

828さん、829さんありがとうございました
0832nobodyさん05/03/03 20:42:46ID:F2b+bV+t
>一度に@_に入れてるんですよね?

 Oui.
 もし、chompの後に$_で一つずつ処理をするのならば

@_ = <IN>;
chomp @_;
while ($_ = shift @_)
{
〜
}

という事もできます。
0833nobodyさん05/03/03 20:47:32ID:???
>>827
空行で while ループが終わってしまってマズイ気がする。
083483305/03/03 20:48:20ID:???
スマソ。アンカー間違えた。 >>827 じゃなくて >>832 へのレスね。
083583205/03/03 21:11:20ID:F2b+bV+t
>>833

あ、本当だ。スマソ
0836nobodyさん05/03/03 22:01:20ID:???
もう for(<IN>){ chomp; ~~;}でいい。
0837nobodyさん05/03/03 22:58:04ID:???
>>827
sub my_chomp($);

while(my_chomp <DATA>){
...
}
exit;

sub my_chomp($)
{
$_ = shift;

chomp;
return(defined $_);
}
0838829=83305/03/03 23:52:40ID:???
俺も定石を外したコーディングをして痛い目に遭ったことが何度もあったので、
結局、定石通り (>>827 の最初のやつ) にするのがベストだと思うようになった。
0839nobodyさん05/03/03 23:59:42ID:Q1wNh1ei
1行のテキストボックスからの入力で、データに改行が入っていたんですけど
なぜでしょうか?(改行押すと送信になる)
データが壊れてしまうので、改行が入らないようにしたいのですが
どうすればいいでしょうか?よろしくおねがいします。
0840nobodyさん05/03/04 00:22:07ID:???
$hoge = s/\n//g;
ん?
0841nobodyさん05/03/04 01:13:12ID:???
>>839
なぜ改行が入ったかは確かに謎だが、たぶん Perl コーディングに関係ない原因だとは思う。
コーディングで解決するなら >>840 みたいにするんだろうなあ。

>>840
それって入力が元々 $_ に入ってるんであって、決して ~ が抜けてるわけじゃないよな?
0842nobodyさん05/03/04 01:17:56ID:???
入力が$_に入っていたとしても$hogeには置換した回数が入るだけ
$_自体が書き換えられる
0843nobodyさん05/03/04 01:24:24ID:???
>>839
何故入るのかは分からないが、それによって壊れるようなプログラムを書くのは良くない。
取得したデータから改行を取り除くほうが安全だぞ。
084483905/03/04 04:55:51ID:???
>>840-841
ありがとうございました。
842の意味がよくわからなかったのでとりあえず
$hoge =~ s/\n//g; を入れてみました。
自分でバグが再現できないので、有効なのかはわかりませんが。。

>>843
うーんまだよく方法がわかりませんでした。CGIで
data<>data<>message message message<>data<>
data<>data<>message message message<>data<>
このように保存してるデータで、一つだけ
data<>data<>message message message<>data<>
data<>data<>message message
message<>data<>
こうなったため、表示が壊れるという感じでした。
初めて自分で1から書いたので・・・
084583905/03/04 05:00:17ID:???
立て続けにすいません
>>841
>たぶん Perl コーディングに関係ない原因だとは思う。

どういう原因が考えられますでしょうか???
0846nobodyさん05/03/04 09:14:20ID:???
JAPUたんいる?
0847nobodyさん05/03/04 10:13:02ID:???
改行コードが送信されてきたと決めつける必要はないわけで。
・・・意図的に送りつけるのは簡単だが。
ファイルへ書き込むまでにいろいろ処理してるでしょ?
処理途中で改行が紛れ込んでしまうことだってある。コーディングミスで。

再現性を確立しないと追いかけるのは難しいなり。
0848nobodyさん05/03/04 12:05:01ID:???
>>839
君はXSSってのを少し勉強したほうがいいよ。
相手が送ってくるものは全てウイルスと思え。
その上でウイルスが送られてきても大丈夫なように作らないと、君のサイトが
ウイルスの配布元になったりするかもしれない。

まあウイルスってのはおおげさだけどね。
0849nobodyさん05/03/04 12:35:30ID:???
iniファイルの投稿を受けつけて、再配布しようと思っています。

iniファイルのままサーバに置いておくと、
ブラウザで見たときに「ファイルの保存」ダイアログが開かずに、
iniファイルの中身が見えてしまいます。
「右クリックして保存しろ」などの注意文を書く、という手もありますが、
せっかく投稿ということで掲示板的CGIも作っているのでCGIを通すことで
ダイアログを開かせることにしました。

CGIはContent-Typeにtextと入れると広告が入るとかでちょっと苦労しましたが、
なんとかダイアログを出させて、正しい中身を送信できるようになりました。
しかし、ここで微妙な問題が残りました。
ダイアログを開いた時のデフォルトのファイル名が、「〜〜.cgi」になってしまうのです。
なんとかして.iniにできないかと調べているのですが、
御存じの方がいらっしゃいましたらお願いします。

# ファイル名が指定できなかったらCGIを通すのはやめて注意文方式にするつもり。
0850nobodyさん05/03/04 13:08:09ID:???
>>849
日本語が変なので却下
0851nobodyさん05/03/04 13:11:12ID:???
print "Content-type: octed/stream\n";
print "Content-Disposition: attach; filename=$file_name\n\n";
とか
0852nobodyさん05/03/04 13:34:06ID:???
perlで画像などのバイナリーファイルのディレクトリ移動をやりたいです。
windowsXPなどで画像・動画ファイルを選択して切り取りして上の階層に貼り付けるみたいな感じです。

普通に
open FH,"$filename";
my @file = <FH>;
こういう感じでバイナリーファイルも問題なくコピーできるんでしょうか?

それとも何かオススメのモジュールがありますか?
085385205/03/04 13:41:24ID:???
試したら壊れましたorz
どうすればいいんですか?
0854nobodyさん05/03/04 13:42:11ID:???
>>851 うまくいきました。ありがとうございます。
>>852 rename でだいたいうまくいく。うまくいかない場合はFile::Copyモジュールのmoveメソッド、だってさ。
085585205/03/04 14:07:07ID:???
>>854
renameでできました。カレントの中にあるディレクトリ名だけを配列に入れたいんですが、
なにか言い方法はないでしょうか?
globでできるのかなと色々試してますが、ディレクトリだと判断できません。
■ このスレッドは過去ログ倉庫に格納されています