1 名前:デフォルトの名無しさん mailto:sage [2006/12/21(木) 22:35:39 ] "The duct tape of the Internet" こと、Perlについての質問箱です。 "There's more than one way to do it" ということで、Perlの奥深さについて皆で語り合い、追求してまいりましょう。 CGIについての質問は板違いです。WEBプログラミング板でどうぞ。 CGIとPerlの区別がつかない人もWEBプログラミング板に行ってください。 (WEBプログラミング板 pc8.2ch.net/php/ ) CGIの質問は答えがPerlと全然関係ない話に帰着する場合が多かったりするのでWEBプログラミング板に行って聞いたほうが得ですよ。 このスレでは(CGI以外の)純粋にPerlのみに関係する質問を取り扱っていこうと思います。 スレ違いの質問にはスルーか、速やかな誘導をお願いします。 www.perl.org/get.html ● 2006/12/21現在の最新版: 5.8.8 ● 2006/12/21現在の開発版: 5.9.3 前スレ Perlについての質問箱 28箱目 pc8.2ch.net/test/read.cgi/tech/1162273941/ リンク集は>>2-3 過去スレは>>4
552 名前:デフォルトの名無しさん mailto:sage [2007/02/01(木) 00:05:34 ] >551 うおっ! ありがとうございます!! さっそくそのキーワードで調べてみます!!
553 名前:デフォルトの名無しさん [2007/02/02(金) 13:47:58 ] perlでISHテキスト←→バイナリ変換するモジュールってある? 一通りCPANしたりぐぐったりしてみたが見つからなかったんだけど。
554 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 15:02:25 ] 質問です。 項目数(列数)が多いCSVのデータを読み込んで処理するとき、皆さんはどうしてますか? 私は10項目くらいでしたら my($id, $name, $age, ..) = split /,/; と、それぞれ変数を用意するのですが、 100項目を超えるような場合、項目名を要素とする配列を用意しておき @col_name = qw(id name age ..); 連想配列に格納して my @array = split /,/; my %hash = (); for(0..$#col_name) { my $key = $col_name[$_]; my $val = $array[$_]; $hash{ $key } = $val; } $tel = $hash{tel}; 今扱ってるCSVはデータの件数(行数)が500件あって、上記の連想配列の格納をその件数分繰り返し行なっています。
555 名前:554 mailto:sage [2007/02/02(金) 15:03:04 ] 「項目名 => 項目番号」の連想配列を用意しておくのがいいのかなとも思うのですが、 %col_no = ( id => 0, name => 1, ..., ); $tel = $array[ $col_no{tel} ]; ↑ちょっと読みづらいかなとも思います。 項目数・項目名が変わる可能性は低いです。 効率よりも読みやすさ重視です。 よろしければ、ご意見お聞かせください。
556 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 15:07:30 ] $tel = $array->[$i]->{'col_no'}->{'tel'};
557 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 15:09:34 ] $tel = $array->[$i]->{'tel'}; これでいいのか 入れ方は任せる
558 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 18:22:13 ] @col_name = qw(id name age); # member $_ = "1,hiroyuki,30"; # csv @$record{@col_name} = split /,/; # print $$record{id},"\n"; print $$record{name},"\n"; print $$record{age},"\n";
559 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 21:32:19 ] 利便性の為にハッシュを使わざるを得ないのが気になってるんじゃないの? 配列でやりたいなら、こんなことしちゃったり: my $r = MyRecord->new(split /,/); print("$r->name\n"); package MyRecord; BEGIN { my $i = 0; my @col_name = qw(id name age); # カラム名を設定。 for my $n (@col_name) { eval qq{ sub $n :lvalue { \$_[0][$i] }}; $i++; }} sub new { bless [@_[1..$#_]], $_[0]; }
560 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 21:34:18 ] ミス。 print("$r->name\n") 修正 → print($r->name, "\n")
561 名前:デフォルトの名無しさん [2007/02/02(金) 22:02:33 ] >>559 evalで作るのと、*{...} = sub{}で作るのどっちがスマートなんだろ。
562 名前:デフォルトの名無しさん mailto:sage [2007/02/02(金) 22:22:43 ] evalはパーサが動く分遅くはなりそうだけど 通常の定義と見た目が一貫してるから読みやすいかも。 シンボルテーブル+クロージャだと、クロージャ作る側のレキシカルな環境?も意識しないとならないし、ちょっと嫌。
563 名前:554 mailto:sage [2007/02/03(土) 10:09:16 ] >>556-562 ご回答ありがとうございます。 いろいろ方法があるのですね。 まだご回答の内容が理解できていないので、勉強してきます。
564 名前:デフォルトの名無しさん mailto:sage [2007/02/04(日) 09:24:15 ] 他人が作った、FTPで複数のファイルを受信する為の処理に手を入れなくては いけないのですが、元のソースにエラー時の処理が全く入っていません。 $ftpcmd = ○○○ #<-ftpコマンドが記述されたテキストファイル system("ftp -n < $ftpcmd); 対象ファイルは複数あって mget logfile*.* で取って来ています。 ファイルが取って来れなかったり、相手に接続できなかったりといったような エラーが起きた事を判定するにはどのようにすればいいのでしょうか? PerlもLynuxも初めてなので、出来るだけ簡単な方法を教えていただけると ありがたいです。 よろしくお願いします。
565 名前:デフォルトの名無しさん mailto:sage [2007/02/04(日) 13:04:46 ] Net::FTP で書き直したらいいんじゃないかな。
566 名前:デフォルトの名無しさん mailto:sage [2007/02/04(日) 15:35:04 ] >>564 Net::FTPでスクリプト書く例 search.cpan.org/~gbarr/libnet-1.20/Net/FTP.pm モジュールが入ってなかったら「perl CPAN」でググってCPANの使い方覚えていれろ
567 名前:デフォルトの名無しさん mailto:sage [2007/02/04(日) 16:26:22 ] Lynuxはおらも初めてだ
568 名前:デフォルトの名無しさん mailto:sage [2007/02/04(日) 17:13:07 ] >>565-566 そのやり方で書き直してみます。 ありがとうございました。 >>567 Linuxの打ち間違いですね。
569 名前:デフォルトの名無しさん mailto:sage [2007/02/05(月) 23:30:35 ] >>565-566 教えていただいた方法で組んでみたのですが、複数のファイルをワイルドカードで 指定して取って来るにはどうしたらよいのでしょう? 対象のファイル名には出力された日付と時刻が含まれていて、個数も名前も不定 なのです(○○○YYYYMMDDHHMM.logのようなファイル名で、日付部分が 当日のものだけ取って来たいのです)。 何度もすみませんがよろしくお願いします。
570 名前:デフォルトの名無しさん mailto:sage [2007/02/06(火) 01:45:03 ] sub mget { my($ftp,$pattern) = @_; foreach my $file ($ftp->ls($pattern)) { $ftp->get($file) or warn $ftp->message; } }
571 名前:デフォルトの名無しさん mailto:sage [2007/02/06(火) 23:22:19 ] >>570 どうもありがとうございます。 上手く持ってこれました。
572 名前:デフォルトの名無しさん [2007/02/07(水) 11:31:08 ] 希望結果を得たいのですが、実行結果の通りになります 以下のソースで実行結果になることは納得できるのですが、 希望結果を得るためにはどうすれば良いのでしょうか? ●ソース @$data=( {'name'=>'test1','pay'=>'1000','cancel_flg'=>'0','create_date'=>'20070131','cancel?date'=>''}, {'name'=>'test2','pay'=>'2000','cancel_flg'=>'1','create_date'=>'20070110','cancel_date'=>'20070120'}, {'name'=>'test3','pay'=>'100','cancel_flg'=>'0','create_date'=>'20070201','cancel_date'=>''}, ); foreach(@$data){ push(@lst,$_); if($_->{cancel_flg}){ $_->{create_date}=$_->{cancel_date}; $_->{pay}="-".$_->{pay}; push(@lst,$_); } } print "$_->{name}\t$_->{pay}\t$_->{create_date}\n" foreach(@lst); ●実結果 test1 1000 20070131 test2 -2000 20070120 test2 -2000 20070120 test3 100 20070201 ●希望結果 test1 1000 20070131 test2 2000 20070110 test2 -2000 20070120 test3 100 20070201
573 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 11:44:59 ] foreach(@$data){ push(@lst, {%$_});
574 名前:デフォルトの名無しさん [2007/02/07(水) 11:55:08 ] >>573 ありがとうございます 希望どおりの結果を得られました ハッシュ内のデータを1つずつ別のハッシュに移し替えることで回避していましたが これからはソースがスマートになりそうですw 私が無知なだけだと言う話かも知れませんが、勉強になりました
575 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 12:23:24 ] こういうことだな。 $X = ['A']; $Y = $X; #リファレンスデータのポインタ(?)だけをコピーして、データそのものはコピーしてない。 $X->[0] = 'B'; print $Y->[0]; 結果「B」
576 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 12:36:30 ] ちょっとCPANで調べるとStorableのdcloneとか、 Clone(::More/Fast/PP/Any...)とかなんかたくさんあるんだけど どれを使うのがいいんだよ
577 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 12:39:19 ] 俺は年寄りなのでcancelないときもコピーすんのもったいないと思ってしまう
578 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 13:56:18 ] 辞書みたいなものを作っているのですが、見出し語にダブりが多数あります。 こんな感じで。 <midashi>kuki</midashi> 茎とはクキである。・・・・・ <midashi>kuki</midashi> 茎とはクキである。・・・・・ 見出し部分タグ内が同じ場合のみ、一つ残してダブりのぶんは見出しも本文も消す、 という作業を行いたいのですが、perlで出来ますか? 何を勉強すればよいのか、示唆頂ければありがたいです。
579 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 14:05:52 ] xmlなら、専用のエディタ使う方がよっぽど早くて安全だと思うのだが。
580 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 16:05:05 ] ファイルのパースさえ出来れば楽勝だろうけどたぶんそこが一番の問題だと思う 機械読み取りを考慮した仕様になってればいいんだが
581 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 22:15:16 ] 配列を初期化したいのですが、どのようにすればいいのでしょうか? 引き渡したパスにあるファイル名を配列に入れて、そのファイル1つ1つを順繰りに 処理していきたいのですが、1度処理をした後でもう1度処理を行うと、最初に配列 にセットしたファイル名が配列に残ってしまっています。 下のソースだと、「1回目」と「2回目」のところでは同じ内容のファイル名が表示 されます(2回目では何も表示されないで欲しいです)。 どこがおかしいのでしょうか?ご指導を宜しくお願いします。 sub aa{ ($path) = @_; @localfl; @dir; opendir(DIR,$path) || return(-1); @dir = readdir(DIR); foreach $f (@dir){ if($f =~ /^\.\.?/){ next;}#親&カレントフォルダ(.と..)を除外 $localfl{$f} = $f; } foreach $f (sort(keys(%localfl))){ print("1回目 $f\n"); } undef @localfl;#これでクリア? @localfl = ();#これでクリア? foreach $f (sort(keys(%localfl))){ print("2回目 $f\n"); } }
582 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 22:20:07 ] @localfl と %localfl は別物ですよ
583 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 22:55:59 ] なぜに Perl4 … 変数全部グローバルだし
584 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 23:05:43 ] >>582 @localflには最初から何も入ってなくて、%localflをクリアしてないから 前の中身が残ってるということでしょうか? %localflの中身をクリアすればOKですか(%localfl=""; とか・・?) >>583 すみません、まだPerl触り出して1週間のド素人なもので・・。
585 名前:デフォルトの名無しさん mailto:sage [2007/02/07(水) 23:30:02 ] %localfl = ();
586 名前:582 mailto:sage [2007/02/07(水) 23:36:52 ] とりあえず >>585 の %localfl = (); または undef %localfh; で意図する結果が得られます バグの温床になるのを防ぐために use strict; と use warnings; をお薦めします 変数を宣言するときは my を使ってください 適当に書き直したらこんな感じでしょうか use strict; use warnings; sub aa { my ($path) = @_; opendir(my $dh, $path) or return -1; my @localfl = sort grep { ! /^\.\.?/ } readdir($dh); foreach my $f (@localfl) { print("1回目 $f\n"); } }
587 名前:デフォルトの名無しさん mailto:sage [2007/02/08(木) 00:19:07 ] >>585 >>586 丁寧に教えていただきありがとうございました。 参考にさせていただきます。
588 名前:デフォルトの名無しさん mailto:sage [2007/02/08(木) 20:09:30 ] Encodeモジュール使い方を勉強中です。 なんとか試行錯誤しながらやってるんですが、 Data::Dumper がやたら文字化けします。 Dumper無しで出力すると化けないので エンコードの部分は間違ってないと思うのですが。
589 名前:デフォルトの名無しさん mailto:sage [2007/02/08(木) 20:16:37 ] use strict; use utf8; use Data::Dumper; binmode STDOUT,":encoding(cp932)"; my $str="あああ"; print Dumper $str; print $str; 以上をutf8で書いて実行すると $VAR1 = "\x{3042}\x{3042}\x{3042}"; あああ となります どうにかして日本語をDumperする方法はないでしょうか?
590 名前:578 mailto:sage [2007/02/08(木) 20:17:25 ] ありがとうございました。 XML エディタ で検索してみましたが、どうもよく分かりませんでした。 ちなみに見出しは全部でaからzまで数十万あります。 ダブり語は多分、数千種類が各2〜7個くらいダブっています。 差し支えなければ、使えそうな専用エディタを教えて頂けないでしょうか? ファイルのパースさえ出来れば楽勝だろうとおっしゃるのは素晴らしいです。 ちなみに楽勝というのはperl で、ですか? 機械で読むというのがよく分からないのですが(すみません)、多分txt形式で 50MBくらいのファイルになりそうで、そこまでは出来ます。
591 名前:588=589 mailto:sage [2007/02/08(木) 20:19:08 ] ちなみに環境は WindowsXP sp2 上で、ActivePerl Build 819 使用しています。
592 名前:デフォルトの名無しさん [2007/02/09(金) 02:39:44 ] なんとなくWebProgからきました。取り留めもない質問なんですがお願いします。 WEBの掲示板などでよく、特定のタグだけ書き込み許可してますよね。それを実現するのに 下記のようなコードを書きました。最近、WEBに限らず、テキスト系の処理は何するにも こんな感じでsplitして再帰する書き方に固執してしまってます。 字ヅラ的には短くて気に入ってるんですが、処理的には効率悪い気がしてならないのです。 もっとうまい方法があるでしょうか。 sub escape_limited { my %args = (str => '', @_); $exception = q!</?(?:a|img|blockquote|pre|code|span)(?:\s[^>]*)?>!; my @scraps = split(/($exception)/im, $args{'str'}, 2); if ((scalar @scraps) == 3) { return &escape(%args, str => $scraps[0]). $scraps[1]. &escape_limited(%args, str => $scraps[2]); } else { return &escape($args{'str'}); } }
593 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 04:00:04 ] sub escape_limited { my %args = ( str => '', allowed => qr{a|img|blockquote|pre|code|span}, @_ ); my $text = $args{str}; $text =~ s{( < (?! /? (?:$args{allowed}) \b ) [^>]* > )}{ escape($1) }iegx; return $text; } とかでどう?
594 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 09:53:04 ] $LT = quotemeta escape("<"); $GT = quotemeta escape(">"); ($str = escape($str)) =~s/$LT\/?(a|img|b|blockquote|pre|code|span)\b.*?$GT//ig; とかねー。多分軽いよ。 タグ内に'<' '>' が無いことを前提にしてるみたいだけど、大丈夫? 属性も調べないと、スタイルシートとかスクリプトとか埋め込まれる可能性もあるし。
595 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 10:35:31 ] うおっ、間違えた。正規表現のリテラルのトコ…。 s/$LT(\/?(?:a|img|b|blockquote|pre|code|span))\b(.*?)$GT/<$1$2>/ig だわな。スマソ
596 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 13:59:17 ] 試しました。 592(私):スプリット型 593:一発置換型 594:例外事後処理型 マッチングがひとつもない場合 592:速い 593:圧倒的に遅い 594:速い マッチングがある場合 592:圧倒的に遅い(しかも多重再帰の警告でまくり) 593:少し速い 594:速い 一旦、なりふり構わず置換してから例外を元に戻すってのは、 分かりやすいだけで処理的に気持ち悪いと思ってましたが、 意外と効率いいんですね。
597 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 14:07:03 ] お礼を忘れました。みなさんありがとうございます。 ひとつ、事後処理型の場合、対象文字列に最初からエスケープ文字が 含まれてるケースを考慮する必要がありますね。これが一番やっかいかなあ。
598 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 14:10:29 ] いや、一旦、二重エスケープになって元に戻るからいいのか。 混乱してきたので仕事に戻ります。
599 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 15:02:53 ] >>590 テキスト読み込んで処理はPerlの得意とする分野なので楽勝 タグは<midasi></midasi>だけなのか?その他のタグがあったとして処理する必要はないのか? 複数の同じ見出しに対し残す本文はどれでもいいのか? 本文中にタグや特殊文字があったりした場合は?一意に判別できるエスケープの仕様はある? あたりの仕様さえ確定できればファイル読み込みのやりかた、正規表現、ハッシュあたり覚えればできるっしょ ちゃんとしたXML形式になってるなら専用のパーサ使えば楽が出来るが、正規表現でも十分なように思える
600 名前:デフォルトの名無しさん mailto:sage [2007/02/09(金) 23:36:51 ] ちゃんとしたXMLになってなくても、XML::Liberal使えばわりといける。
601 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 03:35:34 ] wxperlを使ってGUIのメモ帳を作っています。ファイルを新規に保存するとき ファイルと同名のフォルダをつくりたいのですがなぜかうまくいきません。 my $filename = $saveasdialog->GetPath; $this->{text_ctrl_1}->SaveFile($filename); mkdir($filename); このスクリプトで、一行目でwxperl filedialogオブジェクトにより ファイル名が取得され$filenameに入ります。2行目でsavefileメソッドで テキストが$filenameの通りに名前がつけられ保存されます。これは正常にいきます。 しかし、3行目のコードではフォルダが作成されません。 wxperl固有というよりもperlのコードの書き方に問題があるような気がするのですが、 アドバイスがあったらお願いします。
602 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 03:46:04 ] > ファイルを新規に保存するときファイルと同名のフォルダをつくりたい なんじゃそりゃ??
603 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 03:54:30 ] どの OS でテストしてるんだか知らないけど、ファイルシステム側の問題だろう。 例えば Windows では同名のファイルとフォルダは作れない。
604 名前:601 mailto:sage [2007/02/10(土) 04:31:21 ] >>603 すみませんでした。windows xp, active perl環境です。 >例えば Windows では同名のファイルとフォルダは作れない。 これは知りませんでした。というか大昔に聞いたことがあるような気がしますが 盲点でした。 mkdir($filename."Folder"); のようにしたら("作成したファイル名"Folder)という名前でフォルダが出来ました。 自分の考えている機能としてはこれで十分先に進めそうです。 ありがとうございました。
605 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 13:39:41 ] て言うか、同名のファイルとフォルダを作れるファイルシステムってあったっけ?
606 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 13:43:46 ] 同名のファイルとフォルダがあるとApacheがまいっちんぐしちゃうよ
607 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 15:15:31 ] >>605 むかし、「同名のファイルとディレクトリ作れるんじゃねえ!!」と怒った記憶がある。
608 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 17:42:01 ] これも拡張子を非表示にするゆとり教育の弊害か…
609 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 18:27:55 ] これもファイル名とディレクトリ名を同じ名前空間に置くという異常なことを やったUNIXの弊害か……
610 名前:デフォルトの名無しさん [2007/02/10(土) 18:44:58 ] 初学ながらリファ本片手にCGIスクリプトを書いています。 下記のような問題にぶつかるもどうにも解決方法がわかりません。 どうすればよいか教えてください。よろしくお願いします。 【やりたいこと】 投票CGIの改造で、イエスノーの2択の選択肢の投票に応じて、表示されて いる数字も増減されるようにしたい。 数字の増減はカウンタスクリプトを流用し ています。 【現在書いているスクリプト(抜粋)】 open(FILE, "+<./count.dat") or die("エラー:カウントファイルが開けません"); eval { flock(FILE, 2); }; $counta = <FILE>; seek(FILE, 0, 0); if($item == 1 ){ print FILE $counta+1 } else { print FILE $counta-1 } close(FILE); 【問題点】 例えば現在の$countaの値が100で、値が-1される場合、結果は99となって欲しいのに、990と なって返ってきます。1000から999の場合なども同じです(どうも桁数が減る場合にうまく動作し てくれない模様)。 【解決したいこと】 100が99になって欲しい場合、その動作が990とならず希望どおり表示されるようにしたいです。 【その他】 同じ桁数が変わる場合でも、99→100など、桁数が増える場合は問題が発生しないです。
611 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 18:45:26 ] ファイル名とディレクトリ名の名前空間が異なるなんて想像したら そちらの方が異常だと思うが。 そもそもそいった実装のOSはあるんかえ?
612 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 18:58:46 ] >>609 最近それで頭に来てる。百万個を越えるファイルを持つ非常に巨大なファイルツリーを トラバースするのにリソース食いまくり。 やっぱり分けてあるシステムってあるんだ。
613 名前:デフォルトの名無しさん mailto:sage [2007/02/10(土) 19:19:45 ] >610 use Fcntl qw/:flock/; open my $fh, '+<', './count.dat' or die $!; eval { flock $fh, LOCK_EX }; $count = <$fh>; seek $fh, 0, 0; print $fh $item == 1 ? $count + 1 : $count -1; truncate $fh or die $!; close $fh;
614 名前:610 mailto:sage [2007/02/10(土) 19:27:24 ] >>613 正直、書かれている内容がさっぱり分からないので、リファ本で読み進めながら テストしたいと思います。ありがとうございます。
615 名前:610 mailto:sage [2007/02/10(土) 21:14:23 ] >>613 早速アドバイスを実装したところ、思った通りに動いてくれました。 どうもtruncateがポイントだったようですね。ありがとうございました。
616 名前:デフォルトの名無しさん [2007/02/11(日) 04:18:34 ] 正規表現でマッチしたものを任意の変数に入れて(もしくは任意のエイリアスに結びつけて)、 後で取り出すことって出来るのでしょうか? マッチした順に$1や$2ではなく、(.*?>$name)とかした時、 (.*?)のマッチを$nameで受け取れると非常に嬉しいのですが。。 どなたかアドバイスいただけると嬉しいです。。
617 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 05:58:10 ] >>616 マッチした後に代入しておくんじゃなんで駄目なんだ? if (/(.*?)/) { $name = $1; }
618 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 06:01:14 ] >>616 マッチしたもののリストが返ってくるのでそれを受け取る ($a, $b) = /^(.)(.)/;
619 名前:616 mailto:sage [2007/02/11(日) 09:49:39 ] >>617-618 返信ありがとうございます _ _ なぜエイアリアスに結びつけたいかというと βのウェブサービスのラッパーを作っていて、 正規表現がころころ変わる可能性がある(欲しい文字列が前後する可能性がある)からです。 欲しい文字列が前後してしまうと正規表現だけでなく、 その後の正規表現を受け取るコードも変更しなければならなくなってしまうので。。 # 正規表現を正規表現で自動生成するスクリプトを作っていたら、 # 文字列が前後した場合その部分は自動化できなくなってしまうことに気づき、 # 質問させて頂きました。
620 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 11:04:20 ] >>588 ,599 それは文字化けでなく、エスケープされてるだけ。 Data::Dumper の仕様
621 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 11:30:06 ] 詳説正規表現第2版 7.8.8 名前つきキャプチャを模倣する (.*?)(?{ $name = $^N })
622 名前:592 mailto:sage [2007/02/11(日) 15:22:43 ] タグそのものだけでなく、例えば<pre>の内側はエスケープしない、など、 ちょっと込み入っている場合、例外事後処理だと信じられないほど遅くなりました。 コーディングに問題があったかも知れませんが。 という訳でスプリット型に戻しました・・。もっとうまい方法があるでしょうか。 sub escape_limited { my %args = (str => '', exception => [], exception_block => [], @_); my @regexp_array; (scalar @{$args{'exception_block'}}) and push(@regexp_array, sprintf(q!<(%s)\b.*?>.+?</\2>!, join('|', @{$args{'exception_block'}}))); (scalar @{$args{'exception'}}) and push(@regexp_array, sprintf(q!</?(?:%s)\b.*?>!, join('|', @{$args{'exception'}}))); return &loop($args{'str'}, join('|', @regexp_array)); sub loop { if ($_[1]) { my @scraps = split(/($_[1])/is, $_[0], 2) ; return &escape($scraps[0]). $scraps[1]. &loop(pop(@scraps), $_[1]) if ((scalar @scraps) >= 3); } return &escape($_[0]); } }
623 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 18:28:22 ] >>619 たぶんアプローチが根本的に間違ってる。
624 名前:616 mailto:sage [2007/02/11(日) 19:05:54 ] >>621 ありがとうございます!知らなかったです使わせて頂きます。 search.cpan.org/dist/perl/pod/perlre.pod >>623 良くあるので、今回もそうかもしれないのですが; www.nicovideo.jp/ の検索のラッパーとして、 www.kiseki.info/niko-per/matome_search.cgi を作りました。 そして、上記ラッパーの正規表現生成に、 www.kiseki.info/niko-per/regexNikoniko.txt というコードを使っていました。(>>621 さんのアドバイス未導入コード) お暇があればアドバイスいただけると幸いです。
625 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 22:38:26 ] 前から疑問に思ってたんですが、 $input = 'hoge'; $output = $input; $output =~ s/ho/ha/g; return $output; これを$outputを使わずにreturn &func($input, /ho/, 'ha'); みたいに表現することはできないんでしょうか。
626 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 22:54:33 ] こんなん? join('ha', split(/ho/, $input))
627 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 23:09:34 ] return str_replace('ho', 'ha', $input);
628 名前:デフォルトの名無しさん mailto:sage [2007/02/11(日) 23:11:41 ] >>627 どこの国のPHPだよ
629 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 00:06:59 ] 関数的な操作が充実してる割に標準でついてる関数がほとんど破壊的なんだよな
630 名前:592 mailto:sage [2007/02/12(月) 00:10:16 ] すみません、うそを言いました。594さんのがやっぱり一番速いです。 遅くなったのはバグでした。スレ汚しすみません。
631 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 02:58:08 ] パッケージが提供してる関数の一覧って簡単に取得できますか?
632 名前:631 mailto:sage [2007/02/12(月) 03:15:00 ] ちょっとぐぐったら見つかりました。すみません。 search.cpan.org/~mlfisher/pmtools-1.01/pmeth サブクラスなどにもぐっていく処理もありますが、どうもこの行がミソのようでした。 keys %{ "$module::" }
633 名前:デフォルトの名無しさん [2007/02/12(月) 07:44:44 ] 動的に生成された複数のPNG画像データをzip圧縮したいと考えています。 GDモジュールとArchive::Zipモジュールが活用できそう、 と調べたのですが不明点があります。 Archive::ZipモジュールのaddFileメソッドは引数としてファイル名が必要ですが、 GDモジュールのpngメソッドで動的に生成されたPNG画像データをzip圧縮するにはどうしたら良いでしょうか。 生成されたPNGデータをbinmodeを使用して画面表示するサンプルは見かけたのですが・・・ Perlを勉強し始めたばかりで基本事項も良く分からず五里霧中です。 アドバイスのほど、よろしくお願いいたします。
634 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 09:40:25 ] addString
635 名前:デフォルトの名無しさん [2007/02/12(月) 13:43:39 ] system() で所定の場所からwgetでファイルを持ってくる処理を作っています。 必ずしもその場所にファイルがあるとは限らないので、ファイルが無かった時と 接続出来ないなどで取ってこれなかった時を判定したいのですが、どうすれば よいのでしょうか?
636 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 13:47:37 ] system関数の戻り値でチェックできないの?
637 名前:デフォルトの名無しさん [2007/02/12(月) 14:20:49 ] >>636 ありがとうございます。 やってみましたが、ファイルが無かった時も接続できなかった時も、戻り値は 256となるので区別がつかないです・・。
638 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 14:21:07 ] wgetの複雑な機能をバリバリ使ってるなら別だが、ただファイルとってくる だけならLWP使う方がその辺のエラー処理は書きやすいと思うけどな。
639 名前:デフォルトの名無しさん [2007/02/12(月) 14:39:33 ] >>638 すみません、wgetを使わないといけないので別の方法で取ってくるというのは 出来ないのです。
640 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 15:06:35 ] 美しくないがstderr読むしかないだろう
641 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 15:11:25 ] 接続とファイル存在チェックだけ別ルーチンで作っといて、 それがOKならwgetで取ってくるってのはどうだ?
642 名前:デフォルトの名無しさん [2007/02/12(月) 15:59:14 ] >>640 ,641 ありがとうございます。>>640 さんの方法の方が簡単そうなのでこちらで いこうと思うのですが、 open(STDERR, ">> errmsg.txt"); $ret = system("wget 〜"); close(STDERR); とやって、$ret が256 だったらerrmsg.txtを1行づつ読み込んで [ 404 Notfound ]という文字列が見つかったらファイルなし、無い ならその他のエラー、という感じでいいのでしょうか?
643 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 16:27:24 ] というかwgetはちゃんと終了コード返すけど? # wget -q www.google.com/ && echo ok ok # wget -q www.google.com/nonexist || echo ng ng #
644 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 16:28:39 ] あーごめん、404と接続できなかった時とを区別したいのか。早とちりスマソ。
645 名前:デフォルトの名無しさん mailto:sage [2007/02/12(月) 20:57:32 ] 気にしてへんからええよ。 書いてくれてありがとな。
646 名前:デフォルトの名無しさん mailto:sage [2007/02/13(火) 00:23:46 ] >>642 perldoc IPC::Open3
647 名前:デフォルトの名無しさん [2007/02/14(水) 00:10:02 ] 数字と文字が混在した要素からなる配列があるんですけど、これをsortすると 1〜〜,11〜〜,2〜〜,23〜〜・・・ という風になってしまいます。 これを数字順 1〜〜,2〜〜,11〜〜,23〜〜・・・ にするにはどうすればいいのでしょうか??
648 名前:デフォルトの名無しさん [2007/02/14(水) 00:17:12 ] >>647 @dst = sort { $a <=> $b } @src; # 数値ソート @dst = sort { $a cmp $b } @src; # 文字列ソート(こっちは略せる)
649 名前:デフォルトの名無しさん [2007/02/14(水) 00:39:50 ] >>648 それ試したんですけど、数字順にならないんです・・orz
650 名前: ◆TWARamEjuA mailto:sage [2007/02/14(水) 00:49:01 BE:3049474-2BP(6811)] @dst = sort { sprintf qq|%02d|,$a cmp sprintf qq|%02d|,$b } @src; とかとか♪
651 名前:デフォルトの名無しさん [2007/02/14(水) 00:53:47 ] >>650 Sort subroutine didn't return a numeric value ってエラーがががorz
652 名前:脱帽 mailto:sage [2007/02/14(水) 00:59:09 ] ちょうてけとう @dst = sort { ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0] } @src;