Perl初心者スレ(マジレス回答)
wrote_numが何か分からんけど my %rec; はwhile内にしたらどうですか あと、$rowはハッシュのリファレンスだろうから$row->{'id'}では >>467 すみません、レス用に書き換えた元がwote_numでした 下記の様に変えましたが、アクセスできません。 意外と難しいですね。 use Encode; use utf8; my %table; open (FILE, "<:utf8", "hash.txt") or (die "$!"); while(my $line = <FILE>){ chomp($line); @d = split(/\t/, $line); my %rec = ('id' => $d[0], 'count' => $d[1], 'name' => $d[2]); $table{$d[0]} = \%rec; print encode('cp932', $table{$d[0]}{'id'})."\t". encode('cp932', $table{$d[0]}{'count'})."\t".encode('cp932', $table{$d[0]}{'name'})."\n"; } close(FILE); print Encode::encode('cp932', "読込完了\n"); foreach my $row (@$table){ print encode('cp932', $row->{'id'})."\t". encode('cp932', $row->{'count'})."\t".encode('cp932', $row->{'name'})."\n"; } print Encode::encode('cp932', "$出力完了\n"); 実行結果:まだアクセスできません >hash_test.pl 1 10 テスト1 2 5 テスト2 読込完了 出力完了 これでいけると思いましたが、玉砕でしたw foreach my $row (@$table){ while (my ($id, $count, $name) = each(%row)){ print encode('cp932', "$id\t$count\t$name\n"); } これでいけました! foreach my $row (keys %table){ print encode('cp932', "$table{$row}{'id'}\t$table{$row}{'count'}\t$table{$row}{'name'}\n"); } >hash_test.pl 1 10 テスト1 2 5 テスト2 読込完了 1 10 テスト1 2 5 テスト2 出力完了 ただ、key を外して foreach my $row (%table)とすると下記の通り改行が入ります 1 10 テスト1 2 5 テスト2 出力完了 これで全てのハッシュ要素を出力できますが、 カラム順が不確定になってしまいますね。 ハッシュなので仕方ないことですかね。 foreach $row (sort keys %table) { foreach $col (sort keys %{$table{$row}}) { print encode('cp932', "$table{$row}{$col}\t"); } print "\n"; } >hash_test.pl 1 10 テスト1 2 5 テスト2 読込完了 5 2 テスト2 10 1 テスト1 出力完了 >>471 キーだけ別の配列に取っといてそれ使えば? >>472 できれば要素をカラム名でアクセスしたいのでハッシュの方がいいのですが、カラム順固定出力は配列しかないということですね。 >>471 foreach $col (sort keys %{$table{$row}}) { を foreach $col (qw/id count name/) { とかでは? keyの名前も順番も分かってるんだし。 自分が昔質問したことにたいして今なら回答できる <> は <STDIN> の単なる略ではなく @ARGV が捕れない副作用があった そこに詰まっていた #!/usr/bin/env perl use 5.010; if (-p STDIN) { print "May be pipe is used. I've got STDIN as below\n"; # my @lines = <STDIN>; # when <> used, perl think no @ARGV map {state $i; ++$i;print "$i $_" } <STDIN>; } else { print "This may be just single running.\n"; } map {state $i; ++$i; print "$i argment found ==> $_\n"} @ARGV; タグを除去したいのですが、<>も文に入っているため <.*?>ではなく<("[^"]*"|'[^']*'|[^'">])*>を使いたいのですが perl -pe '<("[^"]*"|'[^']*'|[^'">])*>' にする場合どれどれをエスケープすればよいでしょうか? ’だけだと動きませんでした。 perl -pe '<("[^"]*"|\'[^\']*\'|[^'">])*>' 除去?だったらs/パターン//gみたいにやらないと何も変わらないのでは? てか、それエラーにならないの? 5chの書き込みのほう、つけ忘れてました perl -pe 's/<("[^"]*"|'[^']*'|[^'">])*>//g' です perl -pe 's/<.*?>//g'は動くんですけど perl -pe '<("[^"]*"|\'[^\']*\'|[^'">])*>'だと動かないんですよね またやっちゃった perl -pe 's/<("[^"]*"|\'[^\']*\'|[^'">])*>//g' こうか? perl -pe 's/<("[^"]*"|'"'"'[^'"'"']*'"'"'|[^'"'"'">])*>//g' perlというよりシェルのシングルクォートの問題 そこまでするくらいなら HTML::Parser を使う方がいいと思うよ。 >481 できました!、ありがとうございます。 'を'""'で括るのですね なんで\でエスケープにならないんでしょうね パーサーも一度使ってみたんですが <p>hoge</p><p>hoge</p> pタグが一行に2つあると誤作動したりするんですよね その誤作動がパーサーのせいかどうかは判らないが、少なくとも HTML::Parser でそんなことは起こらないから安心してほしい。 たとえばテキスト部分だけを出力したいならこんな感じでできる。 my $parser = HTML::Parser->new( text_h => [sub { print( $_[0]) },'text'], ); $parser->parse_file( \*STDIN); >485 参考になります。 パーサーもいろいろ種類あるみたいですね。 自分の使ってたのはhtml-xml-utilsというやつでした。 @aに0を100ケ追加するには、pushをforで100回回す以外の方法ありますか >>488 ありがとうございました 俺が遅くなりまして申し訳ありません 二つ以上の空白文字列を 一つの空白に変えたいのですが うまくいきません。 if($line=~/\s\s+/){ $line=~s/\s\s+/\s/g print("$line\n") } s/\s\s+/ /g; でうまくいったよ。 そうか、\sって正規表現だから、置換文字列に使うと「perl にそんな定義ないで!」ってなるのか。 これは俺も気を付けよう。 置換といえばこのまえ、JSONで取得したUnicodeを表示したくて、 \u3042 → \N{U+3042} に置換しようとしたけど、できなかった。 \N{U+ }←ここにはリテラルしか書けないのかな。 if文で真偽値を判定するのってどうやるの? hoge() or die("Error\n"); ってなってた(hoge()の戻り値が魏ならエラー)のを標準出力したくて my $a = hoge(); if( ! $a ){ print("Error\n"); exit $!; } みたいにしたんだけど、if文の書き方ってこんなんで良いの? >>494 0を返しても、0といb、文字(アスキーコード0x30)として扱われたりするから、俺は if(scalar($a)) { とか if($a eq 0) { とかするよ。 >>494 良い。 ! で条件反転させるんだったら unless 使っても良いと思うけどね。 unless ($a) { ... } みたいに。 良くないんだってば。 Perlをそういう流儀でやってるといつか痛い目にあうよ。 >>495 マジか。 my $a = hoge(); において、左辺が 0、右辺が 0x30 になるのは、言語としてぶっ壊れているんじゃね? そういう言語なの 0 but true なんていう値もあるし 元の hoge() or die("Error\n"); が問題なく動いてるなら hoge() or print("Error\n"), die $!; hoge()が0を返しうるかどうかもわからんと思うのだが >元の >hoge() or die("Error\n"); >が問題なく動いてるなら という前提の下で >>495 の配慮に意味があるの? >>496 で十分 hoge() or が動くという前提を無視するとして もしもhoge()が0を含む数値か失敗を返すなら(空文字を含む文字列か失敗でもいい) 失敗にundefを返してdefinedで受けるのがフツー $_ ← これ、なんて読む? perlが発祥ってわけでもないそうだが(bashとかにもあるんだってね)、ガチのドザなので 俺は内心ドルバーって呼んでる ドル・アンダーバーじゃないかな。 設定によってはチルダの代わりにトップバーってのがあったから、それと区別するのにアンダーって言ってた気がする。 おつあり そういやそんなの(トップバー)あったねえ なるほど なつかしのcgiゲームを設置したくてperlを触ってるのですが、今の時代でもcgiゲームはサーバーへの負荷は大きいのでしょうか?(昔はよくゲームの設置が禁止されてましたが) perlと関係なかったらすみません… StrawberryPerlで $str='あ'; if ($str =~ /^[あいう]$/) {print("match\n");} を実行してみるとマッチしてくれません /^(あ|い|う)$/ ならマッチするのですが 古いPerl4のjperlなら /^[あいう]$/ でもマッチします やはりこれはStrawberryPerlのバグ(または仕様)なのでしょうか print length $str; を入れてみたらわかる >>511 レスどうもです Shift-JISの環境で正しく2とカウントされてます 前記はあくまで例ですので全角文字なら他の文字でもこうなるみたいで ひらがなにマッチさせたいわけではないんです 少なくともperl5.8以降の文字クラスはuse utf8;前提になっててlengthが1じゃないとだめじゃね? 推奨されてないけど use encoding 'sjis' ならsjisでコード書けたと思う jperlナツカシス Windows では Filter::Encoding いれて使ってた スクリプトは utf-8 で書いて use utf8 してたけど コマンドラインでは -MFilter::Encoding=cp932 とか read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる