くだすれPerl(超初心者用)3
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2009/03/31(火) 22:20:27ID:???もしくは質問者自身何が何だが分からない質問を勇気を持って書き込むスレッドです。
Perl使いが優しくコメントを返しますが、
お礼はPerlの布教と初心者の救済をお願いします。
前スレ
くだすれPerl(超初心者用)2
http://pc11.2ch.net/test/read.cgi/php/1204488452/
関連スレ
Perlについての質問箱 39箱目
http://pc12.2ch.net/test/read.cgi/tech/1234181856/
Perlコーディング初心者質問スレ Part 59
http://pc11.2ch.net/test/read.cgi/php/1234752149/
【Perl上級者コーナーPart01】
http://pc11.2ch.net/test/read.cgi/php/1024741312/
0332nobodyさん
2009/10/05(月) 21:32:31ID:???ホームページを取得するコードを書いたのですが、日本語部分が文字化けします。
ググって、chcp 65001やbinmode STDOUT, ':encoding(cp932)';など試してみましたが、解決できませんでした。
既出の質問かも知れませんが、アドバイスいただれば幸いです。
ソース
#!/usr/local/bin/perl
use strict;
use warnings;
use LWP::Simple;
use utf8;
my $url = "http://yahoo.co.jp/index.html";
my $response_string = get($url);
print $response_string;
[環境]
WindowsXp SP3
ActivePerl 5.8.9 Build 826
Windows メモ帳
ファイル保存形式 utf8
コンソール Windows標準コマンドプロンプト
よろしく、お願いします。
0333nobodyさん
2009/10/05(月) 23:18:28ID:???utf-8からcp932に変換したいのなら、from_toを使えばいいと思います。
my $response_string = get($url);
#-- 追加 --------
use Encode;
Encode::from_to($response_string, 'utf8' => 'cp932');
#---------------
print $response_string;
use utf8の基本は、外部から来る文字列は、Perlの内部表現にし(decodeする)、文字列を
外部に出力するときは、Perlの内部表現から所望の文字コードに変換する(encodeする)
です。
Perlの内部表現はUTF-8を使用しているため、UTF-8で入ってくる外部からの文字列は
変換が必要ないと思われがちですが、内部表現でのUTF-8ではUTF-8フラグというのを
立てて、単なるUTF-8(バイナリ列)と、内部表現でのUTF-8を区別しています。
そのため、UTF-8の文字列であろうと、内部表現にするためには、decodeする必要があります。
質問のコードをその理念に基づいて書き直すと、
use utf8;
use Encode;
binmode STDOUT, ':encoding(cp932)'; # 外部への出力(標準出力)は”内部表現”からcp932に変換
my $url = "http://yahoo.co.jp/index.html";
my $response_string = decode('utf8', get($url)); # 外部から来た文字列は内部表現にdecode
#my $response_string = decode_utf8( get($url) ); # 外部からきた文字列がUTF-8の場合はこれでもよい
print $response_string;
0334nobodyさん
2009/10/05(月) 23:45:50ID:???332です。さっそくのご返答、ありがとうございます。
Perlの内部表現、encode、decodeについて、まだ詳しく理解していないので、これから勉強していきます。
サンプルで書いていただいたコード、見事に文字化けなしで動作しました。
2chに書き込むのは、生まれてはじめてだったのですけど、的確なアドバイスをいただいて感激しました。
0335nobodyさん
2009/10/06(火) 16:20:44ID:o5fGVlDsベストは>>329の回答。
どうしてもなら
map { ${ $_ } = $arg{ $_ } } qw(a b c);
0336nobodyさん
2009/10/06(火) 16:30:58ID:???そこを指摘してあげなよw
0337nobodyさん
2009/10/06(火) 19:46:56ID:???シンボリックリファレンスを使ったやり方ですよね。
それはまず最初に試したのですが、動いてくれませんでした。
no strict 'refs' を使ってもダメでした。
理想は>>329さんのやり方なのだとは思うのですが、
実際は配列の中に入っている変数が10数個ある状態ですので
どうしても冗長になってしまいます。
そこをどうにかできればと思ったのですが…。
0338nobodyさん
2009/10/06(火) 20:07:37ID:???use strict;
use warnings;
my %arg = (a => 1, b => 2, c => 3);
{
no strict 'refs';
map { ${ $_ } = $arg{ $_ } } qw(a b c);
}
{
no strict 'vars';
no warnings 'once';
print "$a, $b, $c\n";
}
掟破りなコードだわな。
普通は使わないので、プログラムを練り直してください。
0340nobodyさん
2009/10/07(水) 14:16:38ID:DCSJgtVa0341nobodyさん
2009/10/07(水) 19:56:47ID:OXEUclFZこのファイルが開けないのですが、どーすれば良いのでしょうか。
0342nobodyさん
2009/10/07(水) 22:42:55ID:4Cj4Mzn7開けるよ?
何をどうしたいのか、試した操作は何か書いてください。
0343nobodyさん
2009/10/08(木) 00:00:06ID:???ありがとうございます、動きました…が、やっぱりデータの扱いに問題ありますよね。
元のプログラムでは上のソースを使って変数格納したものが
合計数百カ所くらい使われていて、なかなか修正に踏み切れなかったのですが
この機会に手を入れてみます。重ねてありがとうございました。
0344nobodyさん
2009/10/08(木) 12:48:43ID:OiR61371中身を編集したいのですが
fedora9付属しているGNOMEテキスト・エディタで開こうとして失敗します。
0345nobodyさん
2009/10/08(木) 13:51:45ID:???euc-jpで書かれているっぽいんだけど、
文字コードの認識がうまく行かないのが悪そう
perlでeuc-jpで読んで
utf-8におき替えてから編集すれば良くね?
0347nobodyさん
2009/10/08(木) 16:46:58ID:pWiOQ0nrどうすればperl上で編集できるのでしょうか?
無知ですみません。
0348nobodyさん
2009/10/08(木) 17:21:14ID:???こんなんでどう?
-- euc2utf.pl -------
use Encode;
$ARGV[0] =~ /(.*)\.(.*?)$/;
open my $out, ">$1_utf8.$2" or die $!;
while (<>) {
Encode::from_to($_, 'euc-jp' => 'utf8');
print {$out} $_;
}
close $out;
コマンドラインより
perl euc2utf.pl keywordlist_furigana.csv
で、keywordlist_furigana_utf8.csvというファイルができる。
0349nobodyさん
2009/10/08(木) 22:33:48ID:???文字化けするだけ
多分落とすときに壊れたか、パーミッションの問題じゃないか
0350nobodyさん
2009/10/09(金) 00:04:50ID:???文字化けすら許さないらしい。
0351341
2009/10/10(土) 17:39:23ID:7InkIPwkレスありがとうございます。
言われた通りにやったのです、やはり開けませんでした。
(プログラムはエラーなく実行できました。)
>>349-350
再度ダウンロードし、パーミッションも問題ないはずですが開けませんでした。
OSはfedora9です。
0352nobodyさん
2009/10/10(土) 21:07:02ID:???全くPerl関係なくね?
とりあえずviで開いてみたら?
0353nobodyさん
2009/10/11(日) 00:10:19ID:X0n6wGB10354nobodyさん
2009/10/11(日) 01:18:56ID:???while($hoge){
…
} else {
…
}
的な使い方を想定してるなら出来ない
というかどういう状況でこんな処理が必要になるのか想像もつかない
0355nobodyさん
2009/10/11(日) 01:21:55ID:???my %map = ( @cols => @list );
ってな感じでハッシュに一行代入するやり方があったはずなんですが、
やり方を忘れてしまいまして、本当にくだ質ですが、お答え頂けると幸いです。
0356nobodyさん
2009/10/11(日) 01:28:52ID:???こんな感じ?
0358nobodyさん
2009/10/11(日) 01:35:58ID:???my %hash = ($cols[0], $list[0]);
$hash{$cols[1]} = $list[1];
多分このどっちかのことだろ?
0359355
2009/10/11(日) 01:39:42ID:???スライス使うだけですた。
二行にはなりますが、以下で出来ますた。
my %map = ();
@map{@cols} = @list;
0360nobodyさん
2009/10/11(日) 05:54:06ID:X0n6wGB10361nobodyさん
2009/10/11(日) 10:25:57ID:???0362nobodyさん
2009/10/11(日) 11:41:59ID:???肯定の戻り読みを使うとか
my $ignore_bytes = 6
my $search_word = 'foo';
my $str = 'foo--foo--';
$str =~ /(?<=^.{$ignore_bytes}).*$search_word/;
0363nobodyさん
2009/10/12(月) 03:34:02ID:???可読性を考えるなら >>356 を使ったほうがいいと思いますよ。
% で宣言してるのに @ で使うとか、間違いの元だと思うんで。
「動けばいいの!」 って言うんならそれでいいですが・・・
0364nobodyさん
2009/10/12(月) 07:37:11ID:???356でも>>359でも間違える余地なんて無い。
>>359のスライス間違える奴は356でも間違える。
それだったら丁寧にfor使え(for修飾子では無く)
0365nobodyさん
2009/10/12(月) 07:54:23ID:???底辺に配慮してたらキリが無いわな
0366nobodyさん
2009/10/12(月) 10:32:01ID:???0367355
2009/10/12(月) 17:22:45ID:???@とか%はキーワードとして、見ないもんですよ。
どちらかというと[]なのか、{}なのかで型が決まってきますです。
そもそも、生の配列やハッシュを使うとデータ構造に制限しか生みませんです。
0368nobodyさん
2009/10/12(月) 22:45:13ID:???0369nobodyさん
2009/10/12(月) 23:36:14ID:???0370nobodyさん
2009/10/13(火) 00:26:07ID:???0371nobodyさん
2009/10/13(火) 10:43:38ID:???0372nobodyさん
2009/10/13(火) 13:35:24ID:???オブジェクトにして扱えってこと?
Perlだったら、List::MoreUtilsのzip/meshで十分だと思うけどなぁ。
そこまで拘りたい場面なら、がっつりRuby使うかな。
0373nobodyさん
2009/10/13(火) 17:20:52ID:???データはレファレンスで表現するのを基本にするってことでしょ
0374nobodyさん
2009/10/13(火) 17:38:12ID:???中途半端にやるからソースがごちゃごちゃになるのに・・・
0375nobodyさん
2009/10/13(火) 20:16:59ID:???0376nobodyさん
2009/10/13(火) 21:45:13ID:???0377nobodyさん
2009/10/13(火) 23:05:10ID:???配列に生配列は格納できない。
こっちのがよっぽど制限。
0379nobodyさん
2009/10/13(火) 23:39:19ID:???0380nobodyさん
2009/10/13(火) 23:41:11ID:???脳内定義の「生の配列」が何を指し示すのか解らんが、
普通のARRAYの事ならば自分がスライス(>>359)で思いっ切り
使ってる。ハッシュにしても。要するに>>363への反論になってない。
何か別物を指すならそれを説明しなきゃ、伝わる訳無い。
「生ハッシュ」ってのも何だそれ?
普通のHASHの事ならforで回せるぞ?望み通りの結果にはならんが。
perl -Mstrict -Mwarnings -le 'my %h = 1..10 ; for ( %h ){ print $_ }'
ついでに、
>>363はこの程度の初期化で「可読性」って単語を持ち出す
のは止めといた方が良い(しかも可読性を損いがちなmapに対して)。
こっちが赤面する。
0381355
2009/10/13(火) 23:54:32ID:???実際のコードではこうなってますけどね。
@{ $entity_map }{ @$col_list } = @$result_list;
生の配列/ハッシュってのは、『インタプリタが変数展開するもの』ですね。
my @arr1 = (1, 2, 3);
my @arr2 = (4, 5, 6);
my @array = ( @arr1, @arr2 );
的な間違いを仕様で定めて阻止する方が有意義な制限だとは思いませんか?
0382355
2009/10/14(水) 00:07:22ID:???> 普通のHASHの事ならforで回せるぞ?望み通りの結果にはならんが。
> perl -Mstrict -Mwarnings -le 'my %h = 1..10 ; for ( %h ){ print $_ }'
ハッシュ自体を回すのでなく、
for my %map ( @list ) {}
これが出来ないという意味ですね。
0383372
2009/10/14(水) 00:43:00ID:???なんだこれ。
> 的な間違いを仕様で定めて阻止する方が有意義な制限だとは思いませんか?
フラットにするのはPerlの仕様なんだから、Larryにでも提言しろよ。
アホらし。
0386nobodyさん
2009/10/14(水) 00:59:59ID:???ここは超初心者用なんだぜ?
たとえば
not 生 $test = { 'a' => 1, 'b' => 2};
生 %test = ( 'a' => 1, 'b' => 2);
みたいな書き方でお願いします。
0388nobodyさん
2009/10/14(水) 01:06:04ID:???0389nobodyさん
2009/10/14(水) 01:25:13ID:???0390nobodyさん
2009/10/14(水) 01:25:29ID:???0391nobodyさん
2009/10/14(水) 01:59:07ID:???じゃなきゃ 超初心者用スレ に住んでません orz
0392380
2009/10/14(水) 02:09:57ID:???355 perl
「生配列」 => 配列、単次元の配列、etc...
「配列」 => 多次元配列、Array of Hashes、etc...
「生ハッシュ」 => ハッシュ、etc...
「ハッシュ」 => 多次元ハッシュ、Hash of Arrays、etc...
# 355氏の意図とは違うかも知れんが。
少なくとも以下のURLで使われてる言葉の範囲内で説明してくれたら助かる。
ttp://www.kt.rim.or.jp/~kbk/perl5.005/perldsc.html
% perldoc perldsc
そしたら、似た用語を持ち出されて混乱する事も少なくなるでしょうから。
>>381>>382に関しては、、、「超初心者」じゃなさそうだから書く。
アホかと。
後出しもたいがいにしろ。
手前のくだらん妄想に付き合わせんじゃねえよ、ボケ。
0393nobodyさん
2009/10/14(水) 07:58:14ID:???0394nobodyさん
2009/10/14(水) 09:18:29ID:???0395nobodyさん
2009/10/14(水) 10:32:56ID:???ただそれだけなんですか?
テストプログラム作りたいだけなのに、
仰々しく組みたくないから、今のスタイル
でいいや
0396nobodyさん
2009/10/14(水) 14:16:17ID:???こういう勉強を嫌う怠惰な姿勢が、
保守性の悪いコードを生むんだろうね
0397nobodyさん
2009/10/14(水) 18:46:52ID:???0398nobodyさん
2009/10/14(水) 20:27:19ID:???そのデータをさらにラップする必要が出てきたら、
結局リファレンスにするんだから最初からやっとけっつぅ話だ。
0399nobodyさん
2009/10/14(水) 20:56:13ID:???>保守性の悪いコードを生むんだろうね
これが妄想だって言ってんだけど…。
当ってるのかも知れんがね。
自分の心の中で思ってりゃ良い事でしょ?
0400nobodyさん
2009/10/14(水) 20:59:03ID:???これのデータ構造とかを考えた上で保守性万全だと思うなら病院に行け。
適材適所でリファレンスは使えば良いだけだ。
0401nobodyさん
2009/10/15(木) 20:28:53ID:???他人が利用する可能性が少しでもあればリファレンスかな。
正直、規模によるとしか言えんし、普段から使っておいても損でもない。
日曜プログラマや趣味グラマには不要かw
0402nobodyさん
2009/10/15(木) 21:15:52ID:???0404nobodyさん
2009/10/16(金) 22:50:03ID:???0405nobodyさん
2009/10/21(水) 01:54:57ID:???データは TSV で1行あたりタブ3つで、データが4つになるわけですが、
TSV を書くときにタブを2つしか書かずにプログラムを走らせて
my ($tmpZIP, $tmpADDRESS, $tmpTEL, $tmpFAX) = split(/\t/, $line);
の様に split すると、$tmpFAX は undef になってしまうため、
$tmpFAX に対して正規表現つかったり、.= などで文字列を連結させたりすると
Use of uninitialized value というエラーが Apache ログに溜まっていきます。
これを防ぎたいのですが、データ数が足りないまま split したときに undef では無く '' を入れることは出来ないのでしょうか?
今は
my ($tmpZIP, $tmpADDRESS, $tmpTEL, $tmpFAX) = ('', '', '', '');
($tmpZIP, $tmpADDRESS, $tmpTEL, $tmpFAX) = split(/\t/, $line);
とやっています。
0406nobodyさん
2009/10/21(水) 02:01:01ID:???0407nobodyさん
2009/10/21(水) 05:05:56ID:???残念!だったな。
俺は、4代前から、東京生まれの東京育ちの、正真正銘の日本人だ。
お前こそ、朝鮮で生まれて、朝鮮で育った、正真正銘のチョンだろうが。
0408nobodyさん
2009/10/21(水) 07:18:11ID:???こんなんでどうでしょうか?
my ($tmpZIP, $tmpADDRESS, $tmpTEL, $tmpFAX) = ( split(/\t/, $line), (q{})x4 );
0409nobodyさん
2009/10/21(水) 14:00:25ID:???とりあえず、この方法を使わせていただきます m(_ _)m
0410nobodyさん
2009/10/21(水) 14:01:45ID:???(split(/\t/, $line), @nullarray);
もアリかな?
試してないけどw
0411dvKqigko
2009/10/23(金) 01:22:05ID:???0412nobodyさん
2009/10/23(金) 01:31:01ID:???もう遅いかもしれんけどこんな感じでどうよ
my ($tmpZIP, $tmpADDRESS, $tmpTEL, $tmpFAX) = map{defined $_ ? $_ : ''} (split(/\t/, $line))[0..4];
0413rDiWXwyPC
2009/10/23(金) 22:37:05ID:???0414nobodyさん
2009/10/25(日) 12:37:08ID:???ディスパッチャーとは何なんでしょうか?
0417nobodyさん
2009/10/25(日) 14:06:46ID:???0418nobodyさん
2009/10/25(日) 16:54:48ID:???'a' => 'AAction',
'b' => 'BAction',
};
BEGIN {
require $setting->{ $hoge };
$setting->{ $hoge }->new();
}
※$hogeにはあらかじめ規定した、処理の分岐条件が格納されている。
主な部分はこれだけで実現できる。
new以外で処理を行いたいのであれば、サブルーチン名も設定に格納すれば吉。
フレームワークを作りたいのであれば、設定をYAML等に逃がせばよいかと。
0419nobodyさん
2009/10/26(月) 02:45:50ID:4VfuwmZ6マッチさせる対象を
テスト1:10点 テスト2:20点 テスト3:25点 テスト4:20点
にした時テスト3の点数を取り出したいんだ。
テストXの値は不定の文字列なので、
m/\D+\d+\D+\d+\D+(\d+)/;
こう書いたのだけれど$1にはテスト3の点数に加えて4の点数もくっ付いてきちゃうんだ。
何かいい書き方ありませんか?
0420nobodyさん
2009/10/26(月) 02:47:28ID:4VfuwmZ60421nobodyさん
2009/10/26(月) 03:18:05ID:???m/\D+\d+\D+\d+\D+(\d+)/; で問題なく動きました。
0422nobodyさん
2009/10/26(月) 23:59:44ID:???それホントに動いてる?
"テスト2" の 2 を取ってきてない?
そのうちどうせ他の点も必要になるだろ?
関数化すれば便利だと思うよ
sub parseTestData($){
my($str, @pairs, %ret);
$str = $_[0];
$delimitor1 = '\s| ';
$delimitor2 = ':|:';
@pairs = split /\s| /, $str;
foreach my $pair(@pairs){
my($key, $value) = split /:|:/, $pair;
$ret{$key} = $value;
}
return \%ret;
}
my $result = parseTestData("テスト1:10点 テスト2:20点 テスト3:25点 テスト4:20点");
print $result->{"テスト3"}, "\n"; #=> 25点
# 数値だけ取り出したい場合
$result->{"テスト3"} =~ /(\d+)/;
print $1, "\n"; #=> 25
0423nobodyさん
2009/10/27(火) 05:25:43ID:???$delimitor1, $delimitor2 が浮いてるな
0424nobodyさん
2009/10/27(火) 06:07:08ID:???sub parseTestData2($){
return {split(/:|:|\s/,$_[0])};
}
機能はほぼ一緒のはずだ
0426nobodyさん
2009/11/02(月) 17:05:20ID:???どういったものなのでしょうか?
0427nobodyさん
2009/11/03(火) 05:14:37ID:???質問についてはトランザクションについて調べれば後は分かるだろ
0429nobodyさん
2009/11/08(日) 11:29:12ID:OaYz9VK0↑
recv関数は受信失敗したとき未定義ち返すはずなのに
ループ抜けないのはなぜ?
0430nobodyさん
2009/11/08(日) 11:56:56ID:???ていうか本当に未定義値返ってる? 単発で実行したらどうなる?
■ このスレッドは過去ログ倉庫に格納されています