Perlについての質問箱 63箱目
■ このスレッドは過去ログ倉庫に格納されています
CGIについての質問は板違いです。WEBプログラミング板でどうぞ。 CGIとPerlの区別がつかない人もWEBプログラミング板に行ってください。 (WEBプログラミング板: http://kohada.2ch.net/php/ ) このスレでは(CGI以外の)純粋にPerlのみに関係する質問を取り扱っていこうと思います。 スレ違いの質問にはスルーか、速やかな誘導をお願いします。 荒らしはスルー推奨。 "The duct tape of the Internet" こと、Perlについての質問箱です。 "There's more than one way to do it" ということで、 Perlの奥深さについて皆で語り合い、追求してまいりましょう。 www.perl.org/get.html Download Latest Stable Source (5.18.2) ▼前スレ Perlについての質問箱 61箱目 http://toro.2ch.net/test/read.cgi/tech/1381561905/ Perlについての質問箱 62箱目 http://toro.2ch.net/test/read.cgi/tech/1385039352/ >>86 デリファレンスは一度代入しなくてもできるけどちょっとわかりにくいかなって for my $link ( @{ $res->{list}[1]{link} } ) { 新しい書き方だとこんなのもあったり(postfix dereferencing) $res->{list}[1]{link}->@* 1位は「Python」、プログラミング言語別の平均年収ランキングが発表 http://www.mdn.co.jp/di/newstopics/44248/ 2位には「Perl」(平均年収633万円)、3位には「Ruby」(平均年収606万円)がランクインした。 >>67-68 超亀レスですがありがとうございます、勉強になりました! my $date = '平成28年2月26日18:55'; my $week = '金'; $date =~ s/日/日 $week曜日 /; print $date; をすると文字化けするのですが原因がわかりません。 さくらのレンタルサーバーのCGIでPerl 5.14.4です。 $weekを削除すると文字化けはおこりません。 別のプログラムではうまく動いているのですが $week\xe6\x9b\x9c\xe6\x97\xa5になっているみたい プログラム内に入力している日本語がprint表示するときにくずれるようです。 ${week曜日} ${week}曜日 >プログラム内に入力している日本語がprint表示するときにくずれる やっぱutf8フラグかなあ… 日付で教えて下さい 1/23 12:34 を西暦をくっつけて 2016/1/23 12:34に変換したいのですが 例えば未来の日時の場合は 5/1 12:34 を2015/5/1 12:34と1年引いた年にしたいのですが 下のプログラムでは 2015/05/02 06:45:10になります 年の引き算はどうすればいいのでしょうか use strict; use warnings; use 5.010; use Time::Piece; use Time::Seconds; my $t = localtime; my $year = $t->year; my $str = "1/23 12:34"; my $date = Time::Piece->strptime("$year/$str", '%Y/%m/%d %H:%M'); if ($t < $date) { $date -= ONE_YEAR; } say $t->strftime('%Y-%m-%d %H:%M:%S'); say $date->strftime('%Y-%m-%d %H:%M:%S'); >>96 いや、年の引き算って言っても一年は365日とは 限らないんだから、仕様を決めないとだめでしょ? 例えば2月29日の1年前は何日なのか?っていう。 だからそうすると2月29日が出来てしまうって言ってるわけ pythonのスクリプトの頭に、use strict;って書いた。頭いかれてきたw my($year,$month,$day,$hour,$min) = (localtime)[5,4,3,2,1]; my $str = "1/23 12:34"; my($strmonth,$strday,$strhour,$strmin) = $str =~ m|([0-9]+)/([0-9]+) ([0-9]+):([0-9]+)|; if ( sprintf('%02d%02d%02d%02d',$strmonth,$strday,$strhour,$strmin) gt sprintf('%02d%02d%02d%02d',$month+1,$day,$hour,$min) ) { printf("%04d/%02d/%02d %02d:%02d\n",1900+$year-1,$strmonth,$strday,$strhour,$strmin); } else { printf("%04d/%02d/%02d %02d:%02d\n",1900+$year,$strmonth,$strday,$strhour,$strmin); } # 基本に忠実に。応用はそれから >>102 $month -= 2; my $str = "2/29 12:34"; したら、2015/02/29って答が出るコードなんぞ貼るなや 元の質問者のコードに、 ふつうに$obj->is_leap_yearの判定加えて、 2/29跨ぎなら、LEAP_YEAR 引けばいいだけだろ。 要件にない仕様を自己満足で追加してはいけない この件はTime::Pieceだとうまくこなせない問題 融通がきかないのがオレオブジェクトのつらいところだ localtimeとTimelocalは次スレのテンプレに追加するか 同じ質問が繰り返されてみんな同じところではまるからなあ クッキーへの書き込み処理での質問 エラーメッセージを取得処理 print "Content-type:text/html\n"; if(エラー数が0の場合){ 投稿データをクッキーに書き込む処理 } print "\n"; エラーメッセージの表示処理 というようにエラーメッセージの取得と表示の間に print "Content-type:text/html\n";print "\n";を挟む形になってしまうので これらをまとめてサブルーチン化したくてもできません こういう場合でもうまくサブルーチン化できる方法を教えてください エラーメッセージの出力時にContent-typeから出力すればいいのでは >>109 そのためにCGI.pmなどのライブラリや 各種フレームワークがある。 何をしたかったのかよくわからないけど、せめて cookie と書いてほしかった。 住所を入れる変数でさ $adoresu = ・・・ みたいな名前つかうヤツ、いるよね 英語なのか何なのか、よくワカラン $message = エラーメッセージを取得; print "Content-type:text/html\n"; if(エラー数が0の場合){ 投稿データをクッキーに書き込む処理 } print "\n"; print $message; # エラーメッセージの表示処理 my $str = "あああabcあああcdefghあああ123456"; この文字列で半角英数字の部分をAAAに置換するにはどうすればいいですか? あああAAAあああAAAあああAAAになればOKです my $str = "あああabcあああcdefghあああ123456"; print $str, "\n"; $str =~ s/[A-Za-z0-9]+/AAA/g; print $str, "\n"; ありがとうございます。おかげで宿題を提出することができました。 リンク先のページを読んでも何が何だかさっぱり分かりませんでした。 パールでまた問題に直面したら話題を提供してあげますので楽しみにしてるんだぞ。 ファイル演算子の-eと-fの違いは? ファイルが存在するかどうかはどっちを使っても良いのですか? すみません。初めてperlを使うのですが、perlでQRコードを生成したいです。 ブラウザからアクセスしてQRコードの標準出力は出来たのですが、ファイルを生成する方法がわかりません。 以下のソースを実行すると、pngが生成されるのですが、生成されたpngをダブルクリックしても開けなくなります。 use GD::Barcode::QRcode; binmode STDOUT; my $qr = GD::Barcode::QRcode->new('test',{Ecc=>M, Version=>5, ModuleSize=>3})->plot(); open my $fh, '>', 'qr.png' or die; print $fh $qr->png; close $fh; もしお分かりの方がいらっしゃったらお願いします。 >>123 -fは指定されたものが通常ファイルで存在した場合のみ真 -eは同名のディレクトリやシンボリックリンクでも真 >>124 openの次の行にbinmode $fh; >>125 ありがとうございました。 初心者なもので、もう丸一日困っておりました。 centos、zshの環境で、plenvを使っていて、apacheでcgiを動かそうと考えています。 /var/www/html 直下で #!/usr/bin/perl のcgiが動くところまではブラウザで確認できました。 あとはplenvの下記初期設定をするだけ、と思ったところで詰まりました。 export PATH=~/.plenv/bin:$PATH eval "$(plenv init -)" apacheの自動起動では ..zshrc を指定するところがありません。 とりあえず下記で、plenvでインストールしたパスだけは設定したのですが、 eval "$(plenv init -)" の中でどんな処理がされているのかわかりません。 # echo "PATH=/home/centos/.plenv/shims:$PATH" >> /etc/sysconfig/httpd # /etc/init.d/httpd restart eval "$(plenv init -)" ではどんな処理がされているのでしょうか? また、plenvの環境は、パスさえ設定しておけば、特に支障はないのでしょうか? 最後の行だけ。 普通に、echo $(plenv init -)すれば、標準出力に内容が出ます。 >>128 なるほど! 評価してるだけだから、echoで出力できますね。 気づきませんでしたありがとうございます。 echoしなくてもplenv init - だけでいいよw もっとも、それ見た後は そーすこーどみれだけどなw openで開いたファイルをcloseで閉じる前にexitなのでプログラム強制終了した場合 自動的に閉じられてますか? 何か問題ありますか? closeされることが保証されるわけではないが、普通のOSなら OSがcloseを発行する。何を問題とみなすかによるが普通は問題ない cgiなら問題ないけどmod_perlとかだとファイルディスクリプタ消費したままになる exit ではなく die を使うという方法もある。もちろん eval ブロックの中で。 END { close(FILE); } もしくは open(my $file,'file.txt'); だな tmp.datをlog.datにrenameするときrename失敗したら成功するまで繰り返す処理をしたい このようにrename成功したらループを抜けるというやり方でもいいんでしょうか? 他にいいやり方はありますか? for($n=0;$n<=100;$n++){ $rename_seikou = rename("tmp.dat","log.dat"); if($rename_seikou==1){ last; } } 本当にそういう繰り返しをしたいのなら sleep を入れた方がいいと思う。 それから、失敗した時は原因を確認した方がいいと思う。つまり、こんな感じ。 use Errno 'EBUSY'; if ( rename( $src,$dest)){ # 成功 } elsif ( $! eq EBUSY){ # 多分、別のプロセスで使用中。少し待てば成功するかも。 } else { # 待っても無駄だろう。 die( $!); } ごめん、間違えた。 $! eq EBUSY じゃなくて $! == EBUSY 正規表現での置換について質問です。 <ul> <li>あ</li> <li>あ</li> <li>あ</li> <li>あ</li> <li>あ</li> </ul> 上の最後の<li>だけ<li class="a">に置換したです。 1時間以上考えてますができません。 正規表現は少しでもほんの条件が不明瞭であれば誰にも書くことはできない 自己解決しました。 $a =~ s/(^.*)\<li\>(.*$)/$1\<li class\=\"a\"\>$2/s; すみません。 新たな問題が発生しました。 <ul> <li>あ</li> <li>あ</li> <li>あ</li> <li>あ</li> <li>あ</li> </ul> <ul> <li>い</li> <li>い</li> <li>い</li> <li>い</li> <li>い</li> </ul> 上記の文字列が$aに入っている場合で、各<ul>の最後の<li>だけ<li class="a">に置換したいです。 木構造のものを正規表現で置換するのは無理 JavaScriptのjQuery の、addClass, removeClass, toggleClass などを使う それか、HTMLをパースする、ライブラリを探す 否定の文字クラス使えば、普通に最短マッチで出来る事だろ。 s{<li>([^>]*?</li>¥s+</ul>)}{<li class="a">$1}sg パースするライブラリ使えっつーのは同意だがな ああ、否定の文字クラス使わんでも出来るわ。 アホだ俺 >>145 ツリー構造というよりまさにあの並びの時だけの正規表現でいいんでPerlでやりたいんです >>146 ありがとうございます $a =~ s/\<li\>([^\>]*?\<\/li\>\s+\<\/ul\>)/\<li class\=\"a\"\>$1/sg; では動きませんでした そのコードそのまま(円マークをバックスラッシュにして) 動かしたから、何らかの置換↓が得られたけど? <ul> <li>あ</li> <li>あ</li> <li>あ</li> <li>あ</li> <li class="a">あ</li> </ul> <ul> <li>い</li> <li>い</li> <li>い</li> <li>い</li> <li class="a">い</li> </ul> 無意味なエスケープは、コードの邪魔になるだけだからしない方がいいよ。 置換 s/// の右辺は正規表現ですらない(よってエスケープの必要無い)し。 /[0-9]{$num}/ のような量子数は変数にできないんでしょうか?(^^? # 実行してみて for $num (1..3){ $_ = '1' x ($num - 1); print /[0-9]{$num}/ ? 'ok,' : 'not ok,'; $_ = '1' x $num; print /[0-9]{$num}/ ? 'ok,' : 'not ok,'; $_ = '1' x ($num + 1); print /[0-9]{$num}/ ? 'ok,' : 'not ok,'; print "\n"; } >>152 ありがとうございます。 変数は使えたんですね! 演算子が使えないようでした…申し訳ありません。 /[0-9]{$num+1}/ のような使い方がだめでした orz $n = 2; $pat_qr = $n + 1; $pat_qr = qr/[0-9]{$pat_qr}/ ; $pat_ev = eval( sprintf("qr/[0-9]{%d}/",$n+1)); $pat_co = qr/(??{ sprintf("[0-9]{%d}",$n+1) })/ ; print( $_,"\n") foreach $pat_qr,$pat_ev,$pat_co; # 個人的には $pat_qr がいいなぁ。eval を使うほどのことじゃないし $pat_co はデバッグしにくい。 # こうですよ for $num (1..3){ $_ = '1' x $num; print /[0-9]{@{[$num+1]}}/ ? 'ok,' : 'not ok,'; $_ = '1' x ($num + 1); print /[0-9]{@{[$num+1]}}/ ? 'ok,' : 'not ok,'; $_ = '1' x ($num + 2); print /[0-9]{@{[$num+1]}}/ ? 'ok,' : 'not ok,'; print "\n"; } >>155 すごーい\(^^)/ ありがとうございます! >>154 ありがとうございます! あのあのもう一つ ファイルハンドルで3行読み込むのを作ってみたのですがうまくいきませんでした… どうしたらよいのでしょうか… while ( $line[0..2] = <DATA> ) { print $line[0]; print $line[1]; print $line[2]; } __DATA__ なんたら かんたら たらのめ ちょっとサンプル省略しすぎてすみません。 ":encoding(cp932)" 等で漢字の表示は問題ありませんm(__)m while ( $line[0] = <DATA> ) { $line[1] = <DATA>; $line[2] = <DATA>; .... のように分解して書くと問題ありません。(DATAは必ず3行一組になります) 一度に、3行読み込む方法があればお教えくださいm(__)m 都合よく固定長を前提にはできないだろうから、 # 全部読んじゃって chomp(@_ = <DATA>); # 3つづつ処理する while (@line = splice(@_,0,3)) { print map {"[$_]"} @line; print "\n"; } __END__ 1 2 3 4 5 6 7 8 9 $text = 'hoge<span class="hoge" id="hoge">"hoge"</span><span class="huge" id="huge">"hoge"</span>huge'; 上のような文字列で<〜>(タグ内)に囲まれた"だけ $text = 'hoge<span class="hoge" id="hoge">"hoge"</span> <span class="huge" id="huge">"hoge"</span>huge'; 上のような文字列(改行されてますが1行です)で<〜>(タグ内)に囲まれた"だけ " に置換したいです s/(<.*?)"(.*?>)/$1"$2/g; 上のように試してみましたが、最初の1つのみ " に置換されるだけです よろしくお願いします タグの外側だけ置換する方法としては下記がどこかに載っていました s/((?:\G|>)[^<]*?)"/$1"/g; タグの内側だけ置換したい場合は>と<を逆にすればいいかと思ったのですができませんでした >>161-163 $text =~ s{(?<=&lt;)(.+?)(?=&gt;)}{ $1 =~ s/&quot;/"/gr }eg; >>164 ありがとうございます やってみましたがエラーになりました もちろん&は半角に直しました どんなエラーか解らないことにはなんとも…… ひょっとして、5.14 以前の Perl を使ってたりする? >>166 5.8系です AddHandler cgi-script-debugが使えなくなってデバッグができないんです この文法チェッカもいつの間にか消えてました http://homepage2.nifty.com/sophia0/perl.html teraterm入れてSSH登録してエラーチェックしてみました Bareword found where operator expected at test.cgi line 7, near "s/"/"/gr" syntax error at test.cgi line 7, near "s/"/"/gr " test.cgi had compilation errors. 置換の r オプションは 5.14 からです。従来通り perl -pe 's{(?<=&lt;)(.+?)(?=&gt;)}{ ( $str = $1) =~ s!&quot;!\"!g ; $str ; }eg' みたいな感じでどうでしょうか。 >>169 できました! 本当にありがとうございました! (Perl 5.8.8なのにエラーが出たのは謎ですね) そいや5.24でpushやpop,shiiftなどにリファレンスを渡したときの 自動デリファレンスが止めになったのはなぜ? 折角5.14で入れた機能なのに。 なぜも何も。 もともと「実験的に採用した」って宣言してるし、 失敗でした、って delta に書いてあるし。 perlは、常にunstable ♪ オレの人生もunstable ♫ Windows 7で tree D: /f > tree_list.txt これで書き出した物をperlでフルパスに変換したいのですが、 何か良いモジュールなどはありますか? cmd.exe にまかせるがよろし dir /s /b D: 2>NUL >>176 いまいち良い方法が見つからなかった 再帰処理でがりがり頑張ったけど、ものすごい時間が掛かってしまった >>177 ありがとう 無事いけた コマンドライン詳しくないから、NULでひかかった NULの代わりに、list.txtなどにするとサクッと記録された 速度滅茶苦茶早いなー ループの条件を満たしてなくてもredoでループされるんだけど、そうゆうことでいいのかな >redo コマンドは、条件を再評価しないで、ループブロックの始めからもう一度 実行を開始します そうかそうか、これが欲しかった。どうも。 ちょっと相談と言うか、バグの原因が想像つかなくてこまっちんぐなんだけど、 $| = 1; for(.....){ ................ ................. print $x; } みたいな感じでいっぱいプリントしてる時、 プロセス実行中は8.00KB(8192B)しか出力されないんだよね。 本来は9.22KB程度出力されるはずで、これはプロセスが終了したら出力される。 どうしても即時出力したいなら、バッファリングで検索 10GBくらいのCSVで作成された辞書の文字を置換して出力する場合最も適切な方法はどんな感じ? すぐ思いつくのは下記だけど、膨大な回数HDDにアクセスして大丈夫かと不安になるがバッファリングされるから影響はないかな? open(IN,"<Wikipedia.txt"); open(OUT,">>test.txt"); while(<IN>){ $_ =~ s/<|>/<>/g; print OUT $_; } close OUT; close IN; そら最低の理論値でも10GB分HDDから読み出しして10GB分HDDに書き出ししないとな ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる