Perlコーディング初心者質問スレ Part 61
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001nobodyさん
2010/06/05(土) 21:11:10ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ http://pc11.2ch.net/test/read.cgi/php/1251989472/
0825nobodyさん
2010/12/09(木) 18:22:44ID:???while ($html =~ /([-.\w]+@[-.\w])/g)
{ push(@list, $1); }
とやると固まりました。無限ループかもしれません。
どうやったらやりたいことができるでしょうか?
0826nobodyさん
2010/12/09(木) 18:27:51ID:???0827nobodyさん
2010/12/09(木) 18:31:53ID:???0828nobodyさん
2010/12/09(木) 18:45:33ID:???push(@list, $1);
}
$html を後々使うなら
my $html_bak = $html;
みたいにバックアップを。
0829nobodyさん
2010/12/09(木) 18:47:25ID:???同じ内容をひたすらマッチし続けてる
0830nobodyさん
2010/12/09(木) 19:20:57ID:???でできなかったっけ
0831nobodyさん
2010/12/09(木) 19:25:05ID:???0832nobodyさん
2010/12/09(木) 19:42:18ID:???0833826
2010/12/09(木) 20:03:56ID:???@list=($html =~ /([-.\w]+@[-.\w])/g);
>>828
$htmlが$mech->content()だったらどうってことないですよね?
>>829
してたと思います。確実にwhileで止まっていました。
>>831
しかし∞ループしてました。
@list=($html =~ /([-.\w]+@[-.\w])/g);
に入れ替えたとたんうまくいったので。
@list=($html =~ /mailto:([-.\w]+@[-.\w])/g);
としてもメルアドだけのリストができたんだけどどうしてですか?
0834nobodyさん
2010/12/09(木) 20:06:16ID:???0835nobodyさん
2010/12/09(木) 20:13:01ID:???それは真偽値がかえると勘違いしていました。
カッコが必要だと思っていました。正しいのですね。
$baa='abc@abc xyz@xyz 1a2b3c@4d5e';
my @foo = $baa =~ /([-.\w]+@[-.\w]+)/g;
print "@foo\n";
abc@abc xyz@xyz 1a2b3c@4d5e
0836nobodyさん
2010/12/09(木) 20:40:31ID:???実際に動かないコードではない別のコードを捏造して質問するとは駄目な質問者だ。
>>828は無限ループなどにならずにちゃんと機能したぞ。試してみたら。
ただタイプミスのせいで「メールアドレス」は取得し損なってるけど。
たぶん、元の動かないコードに別のバグがあったんだろう。
結局、真の原因はわからずじまいか。
0837nobodyさん
2010/12/09(木) 20:51:36ID:???while ではマッチしたかどうかの判断になるから無限ループになる。
0839831
2010/12/09(木) 21:07:45ID:???いや、whileの話のつもりだったんだけど。
while ( ここはスカラーコンテキスト ) { } だろ。
>>825も一応試したが普通に動いたぞ。
/g がなかったら無限ループだけど。
0840836
2010/12/09(木) 21:21:58ID:???そうだった。アンカーミスった。すまん。
>>839
だからたぶん、元のコードにバグがあって (/g のつけ損ねとか)
質問用に捏造した>>825のコードではバグのないコードを書いてしまったんだろう。
と推測する次第。そうだとすると最低な質問の仕方だよな、とプチ憤ってしまった。
0841nobodyさん
2010/12/09(木) 21:28:12ID:???思い込みじゃなくてテストしてみたらちゃんと動いた。
0842830
2010/12/09(木) 22:03:45ID:???0843nobodyさん
2010/12/09(木) 23:50:50ID:???そんなような理由なんだろうな、たぶん。
0844841
2010/12/10(金) 01:49:22ID:???でフェードアウト的な?
むぅ。。。w
while(/〜/g){ 〜 } がちゃんと回ってくれるっていう事を知れたので、
自分的には有用な流れだった。
0845nobodyさん
2010/12/10(金) 08:34:17ID:???TreeBuilderを使っているのですが、文字化けが微妙な頻度で発生しており
原因の検討が付かず困っています
何かアドバイスがありましたらお願いします
環境はWindowsXP Home、ActivePerl最新verです
以下ソースです
###################
use LWP::Simple;
use HTML::TreeBuilder;
use encoding qw(utf-8);
$uri = "http://blog.esuteru.com/archives/1866797.html";
$tempfile = "getstore.html";
getstore($uri, $tempfile);
my $tree = HTML::TreeBuilder->new;
$tree->parse_file("getstore.html");
for $attr($tree->look_down("class", "article-outer-3")){
$text = $attr->as_HTML('<>&', "\t");
print $text;
}
###################
続きます
0846845
2010/12/10(金) 08:35:50ID:???$uriでアドレス指定した某ブログのとあるエントリを「getstore.html」というファイル名でローカルに保存し、
それをTreeBuilderでエントリ部分だけを抽出して出力する、というものです
上記ソースを「test.cgi」、文字コードUTFで保存し、コマンドライン上で、
>perl test.cgi > test.html
と実行し、出力されたtest.htmlを文字コードUTF前提で開くと一部だけが文字化けしています(下記画像参照)
ttp://www.dotup.org/uploda/www.dotup.org1292408.jpg
当然ですが、元となるページ(ttp://blog.esuteru.com/archives/1866797.html)では該当部分は文字化けしていません
また、この現象は以下に挙げたごく一部にのみ発生し、同ブログ内の他の殆どの記事では何故か発生しません
ttp://blog.esuteru.com/archives/1841660.html
・バグの発生手順の部分2カ所
ttp://blog.esuteru.com/archives/1833321.html
・「(「明日のよいち!」「神のみぞ知るセカイ」他)」の担当者名(「脚本:橋龍也」の部分)
・「◆3DSスパ4」の箇条書きの一部
特定の文字、あるいは複数の文字の組み合わせで発生するような気がするのですが、
当方のスキルではこれが限界でした
思い当たる点ならば何でも結構ですので、アドバイスをお願いいたします
0847845
2010/12/10(金) 08:46:44ID:???発生状況のスクリーンショットです
> ttp://blog.esuteru.com/archives/1841660.html
> ・バグの発生手順の部分2カ所
ttp://up3.viploader.net/net/src/vlnet004648.jpg
> ttp://blog.esuteru.com/archives/1833321.html
> ・「(「明日のよいち!」「神のみぞ知るセカイ」他)」の担当者名(「脚本:橋龍也」の部分)
ttp://up3.viploader.net/net/src/vlnet004650.jpg
> ・「◆3DSスパ4」の箇条書きの一部
ttp://up3.viploader.net/net/src/vlnet004649.jpg
0849nobodyさん
2010/12/10(金) 10:56:09ID:???化けてる行のHTMLソースを見ると、?みたいな数値文字参照があるな。
これが関係していそうだな。
0850nobodyさん
2010/12/10(金) 10:58:22ID:???例えば「&#9314;」(←実際には半角)みたいな文字参照のある行で化けちょる。
0851nobodyさん
2010/12/10(金) 16:37:59ID:???use Encode::Alias;
define_alias( qr/s(hift.*)?jis$/i => '"cp932"' );
0852nobodyさん
2010/12/10(金) 16:52:56ID:???ソースは2chとかじゃなくて元からUTF-8のまとめブログか。じゃあ>>851は意味ないわ。
0853851
2010/12/10(金) 17:30:19ID:???とりあえず結論としては $tree->parse_file のかわりに
my $html = do { local $/; open my $fh, "<", $tempfile; <$fh> };
$tree->parse(Encode::decode_utf8($html));
とすればとりあえず期待通りに動く。
0854nobodyさん
2010/12/10(金) 19:49:59ID:???っていう部分があって、<img> を囲ってる <a> は残して、<a></a> となってるものだけ削除したいと思って
s/<a .*?><\/a>//gi
ってやったんだけど、<img> を囲ってる <a></a> まで削除されてしまいます。
s/<a .*?"><\/a>//gi
これだと意図する動き (<img> を囲う <a></a> は残す) になります。
EmEditor の正規表現検索で試したところ、Perl と同じ動きになりました。
s/<a .*?><\/a>//gi のどこが駄目なのか分かりません。。。
0855845
2010/12/10(金) 19:53:10ID:???回答の提示ありがとうございます
こちらでもうまく動作しているようです
自分の今のスキルではおそらくたどり着けませんでした…
0856nobodyさん
2010/12/10(金) 20:11:14ID:???0回目 <a href="〜"></a><a href="〜"><img src="〜〜〜"></a>
1回目 <a href="〜"><img src="〜〜〜"></a>
2回目
0857nobodyさん
2010/12/10(金) 21:32:40ID:???0858nobodyさん
2010/12/10(金) 21:48:20ID:???m{<a .*?></}で失敗するが
<a href="〜"><img src="〜〜〜">
m{<a .*?>}はマッチする
マッチするものの中で最短
0859nobodyさん
2010/12/10(金) 21:50:49ID:???>>856の「1回目」の場合 .*? にマッチするのは「href="〜"><img src="〜〜〜"」の部分ただ1箇所だけなんだからそこが消えるのは当然。
0860nobodyさん
2010/12/10(金) 22:15:43ID:???じゃぁ、自分がやろうとしてる 「.*?から一番最初に見つかった > まで」 を表現するとすると
<a [^>]*></a>
が正解ってところ?
0861nobodyさん
2010/12/10(金) 22:16:56ID:???<a から最初に見つかった > まで
だった
0862nobodyさん
2010/12/10(金) 22:52:33ID:???こういうのがありえないとわかっている場合や、あっても無視と決め込むなら>>860でいいと思う。
もし厳密にやりたいなら正規表現ひとつでやろうとしないでパーザなりを使うべき。
0863nobodyさん
2010/12/10(金) 23:15:31ID:???> が見つかったんだから、そこで止まれよ
とか思ってたんだけど、そもそも .*? の ></a> がマッチしてるじゃないかと。
ちょっと言葉では表現できないけど、自分の勘違いっていうか、思い込みから来る理解不可能状態に陥ってた。
ありがとん。
>>862
以前 HTML を整形してくれるモジュールがあって、そのモジュールがもの凄いメモリ喰らい (それこそ 数百メガ) で
perl が落ちるってのがあったので (たしかこのスレだったような気がするのだが・・・)、
モジュール使った場合と、自力で書く場合のコード量が少ない場合は自分で書くようにしてたりします。
0864nobodyさん
2010/12/11(土) 16:23:42ID:???こういう話が出てた記憶はあるけどパーサじゃなくて
(Win32環境の)LWPがなぜかくそ重いとかそういう相談じゃなかったかな。
暇つぶしにログ探してみる。
0865nobodyさん
2010/12/11(土) 16:33:48ID:???Perlコーディング初心者質問スレ Part 57
http://pc11.2ch.net/test/read.cgi/php/1203935151/32
0866nobodyさん
2010/12/11(土) 21:07:30ID:???p2 で過去ログあさるのめんどくさいなぁww
ちょっと探してみる
0867nobodyさん
2010/12/11(土) 21:16:11ID:???CGI::Pretty でテーブルを作成したときにメモリ使いまくって、CPU パワー持って言って 500 エラーを返す。 ってやつだった。
http://hibari.2ch.net/test/read.cgi/php/1149017548/136-
今は直ったのかなぁ?
0868nobodyさん
2010/12/11(土) 21:21:38ID:???128行のテーブルで試したら 130MB 使って 500 エラー
4年も経つのにw
まぁ、テーブルぐらいテメェで出力しろってことで。
0869nobodyさん
2010/12/11(土) 22:31:24ID:???わかります。
0870Perl忍者 ◆M5ZWRnXOj6
2010/12/11(土) 22:36:26ID:/agSJrihわかります。
0871nobodyさん
2010/12/11(土) 23:17:59ID:???0872nobodyさん
2010/12/12(日) 14:47:07ID:OtPTT+aF\qw{a b c}
としたらエラーになったので、
[ qw{a b c} ];
としたんですが、あってますか?
でもなんかしっくりこなくて。
0873nobodyさん
2010/12/12(日) 14:58:30ID:???ってぐらい正解でございますw
0874nobodyさん
2010/12/12(日) 15:55:33ID:OtPTT+aF0875Perl忍者 ◆M5ZWRnXOj6
2010/12/12(日) 17:11:01ID:GuB4bd3O0876nobodyさん
2010/12/14(火) 20:11:41ID:???以下のコードのrecvで失敗します。
while (<$sock>)を使うと文字列は読めるのですが、
バイナリデータが読めてなさそうなので、recvに変更したところ
うまくいきません。何か問題がありますか。
my $sock;
socket($sock, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
my $remote_host = 'localhost';
my $packed_remote_host = inet_aton($remote_host);
my $remote_port = 22222;
my $sock_addr = sockaddr_in($remote_port, $packed_remote_host);
connect($sock, $sock_addr);
my $res;
print $sock "Hello";
shutdown $sock, 1;
recv($sock, $res, 100, 0);
close $sock;
0877nobodyさん
2010/12/14(火) 21:47:07ID:???0878Perl忍者 ◆M5ZWRnXOj6
2010/12/14(火) 22:44:39ID:3UzhxS910879nobodyさん
2010/12/15(水) 12:41:57ID:???http://d.hatena.ne.jp/perlcodesample/20090406/1238902770
shutdownを外したらrecvでブロックするようになった。
wiresharkで見ると何か飛んできてるんだけどなあ。
0880nobodyさん
2010/12/15(水) 12:55:00ID:???0881nobodyさん
2010/12/15(水) 15:16:11ID:VvPjVUom0882nobodyさん
2010/12/15(水) 15:32:33ID:???perl処理系のソース読んでスカラーをどう保持してるか
調べてみるといいよ。
0883nobodyさん
2010/12/15(水) 16:40:46ID:VvPjVUom文字列か数値かを判断する方法はないでしょうか?
Devel::Peek でフラグを見る方法だとちょっと大げさすぎるかなと思うので
なにか良い方法はないでしょうか?
最初 +1-1 してチェックできるかなと思ったのですが perl だと意味無いですしね・・
0884nobodyさん
2010/12/15(水) 18:31:17ID:???通常区別する必要がないから組込関数のような形で用意されていないのであって、
必要に感じるのならそれは他の言語の流儀をPerl上でも押し通そうとしているからだ。
どうせ使う前には汚染除去やバリデートをするんだから、単純な整数なら
$num = $num =~ /^([0-9]+)$/ ? $1 + 0 : 0;
のようにチェックのついでに数値化するだけだし、ある文字列が数値として適切に
解釈可能かどうかを調べたいなら Scalar::Util::looks_like_number() がある。
0885nobodyさん
2010/12/15(水) 21:17:32ID:VvPjVUom渡したいのでなんか楽に軽く判別する方法ないかな〜なんて・・・。
YAMLやJSONとかのモジュールの正常性テストとかにも使いたいなとか。
0886nobodyさん
2010/12/15(水) 22:11:31ID:???0887nobodyさん
2010/12/15(水) 23:23:42ID:???0888nobodyさん
2010/12/17(金) 16:39:29ID:???my $str1 = "あ";
my $str2 = "い";
print "$str1$str2";#・・・A
print $str1 . $str2;#・・・B
0889nobodyさん
2010/12/17(金) 17:36:30ID:???実行環境と渡す内容によるし、繋げずに渡してもいい。
print $str1, $str2;
強いて言うなら、特定の条件下でカリカリにチューニングしたいわけでないなら
「読みやすいように」書くといい。
0891nobodyさん
2010/12/18(土) 00:07:20ID:qL35dvRo2、テキストタイプのinputで数字をname="number"で受け取り
cgiで<frame>のタグを繰り返すという内容にしたつもりです。
(内容は下記の状態になってます。)
3、しかし、実行結果のページでは何も表示されません。
何がいけないのかご指摘お願いします。
read(STDIN,$str,$ENV{"CONTENT_LENGTH"});
$str=~tr/+/ /;
$str=~s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("c",hex($1))/eg;
foreach (split(/&/,$str)){
my ($key,$value)=split(/=/,$_);
$input{$key}=$value;
}
$height=100/$input{number};
print "<html>\n";
print "<head><title>first_result</title></head>\n";
print "<frameset rows=\""."$height%,"x($input{number}-1)."$height%\">\n";
for($n=0;$n<$input{howmany};$n++){
print "<frame src=\"second_part.html\" name=\"second\">\n";
}
print "</frameset>\n";
print "</html>\n";
0892nobodyさん
2010/12/18(土) 04:56:26ID:???0893nobodyさん
2010/12/18(土) 05:40:58ID:???せめて use strict; くらいは使おうぜ
0894Perl忍者 ◆M5ZWRnXOj6
2010/12/18(土) 14:12:29ID:lZZb3And0895nobodyさん
2010/12/18(土) 22:45:42ID:eFFNyC2E以下のソースを実行しているのですが…
#========
my $text = "10a|10b|10c";
$text =~ /(10.)/g;
print $1;
print $2;
print $3;
#========
「"10"で始まり、その次の1文字まで含めた値」を全て取得したいのですが、
出力されるのは何故か$1だけで、$2以下は「Use of uninitialized value」とエラーが出てしまいます
マッチした部分は特殊変数$1、$2、$3…と順次格納されると考えていたのですが…
どの部分がおかしいのでしょうか?
0896nobodyさん
2010/12/18(土) 23:05:25ID:???パターン内にあるキャプチャ用のカッコが1つだけだから $2 以降は使われないよ。
my @matches = $text =~ /(10.)/g;
print "@matches\n";
こんな風に配列に入れたらどうかな。
0897nobodyさん
2010/12/18(土) 23:12:09ID:eFFNyC2E自分の正規表現の理解が間違っていたようです
配列で取得する必要があったのですね
ありがとうございました
0898nobodyさん
2010/12/19(日) 01:56:11ID:???while($text=~/(10.)/g){print $1;}
以上蛇足
0899nobodyさん
2010/12/19(日) 17:16:51ID:???0900nobodyさん
2010/12/20(月) 04:07:28ID:???速度的には「,」繋ぎが速いらしいね
""でくくると変数の範囲をチェックするし、「.」で繋ぐと変数の中身を判断するんで、その分遅くなるのだそうな
0901nobodyさん
2010/12/20(月) 12:51:46ID:klkFZZbWその中で文字列を生成→出力と単純な処理を行っているのですが、文字列がある一定の長さを
越えた辺りで、iso-2022-jpで出力するとその長さ前後の数文字だけ\b{xxxx}の形に文字化けします。
eucやutf8で出力すると、化けません。
また、適当な長さのところに改行を入れると、iso-2022-jpでも文字化けしません。
これってどういう現象なのでしょうか..解決先を御存じ、または同じ現象に遭遇した方いらっしゃいますでしょうか。
0902nobodyさん
2010/12/20(月) 12:57:22ID:klkFZZbWすいません、化け方は\x{xxxxx}の間違いです。やはり直前の改行以降300文字前後で化けます。
0903nobodyさん
2010/12/20(月) 13:06:16ID:klkFZZbW実験にこんなプログラムを書きましたが、再現しました。340文字で改行するとOKでした。
#!/usr/bin/perl
use strict;
use Encode;
use utf8;
binmode STDOUT,":encoding(iso-2022-jp)";
my $x;
for(my $i = 0; $i < 1000;$i++){
$x .= "あ";
}
print $x . "\n";
0904nobodyさん
2010/12/20(月) 14:28:44ID:???手元のlinux上の5.10.1で動かしてみたが別に変なことはないけどな。
プログラムは特になんの変哲もないから、現象が本当ならなにかの
バグぐらいしかおもいつかない。バージョンや環境は?
0905nobodyさん
2010/12/20(月) 14:32:42ID:klkFZZbWRedHat ES4 + perl-5.8.5と、FreeBSD 5-STABLE + perl 5.8.8の2つの環境で
確認しました。
perlのバグですかね・・・。うーん。
0906nobodyさん
2010/12/20(月) 15:19:18ID:???does not map to euc-jp at /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/Encode.pm line 158.
途中で euc にマッチするコードになるんだろうか?
binmode を使わないで、最後の方をこうするしかないみたい。
-------------
utf8::encode($x);
Encode::from_to($x, 'utf8', 'iso-2022-jp');
print $x . "\n";
-------------
0907nobodyさん
2010/12/20(月) 15:25:33ID:klkFZZbW最新のEncode.pm(2.40)でもdoes not map to euc-jpと出ました。
5.10.1でOKということはEncode.pmの問題じゃなくて本体の方の問題ですかね。
>binmode を使わないで、最後の方をこうするしかないみたい。
なるほど、確かにこちらならOKでした。
出力先がフィルターやファイルなのでこのまま書き直してうまく行くか確認が
必要ですが、こちらの方で動くか試してみます。ありがとうございます!
0908nobodyさん
2010/12/20(月) 18:35:18ID:???0909nobodyさん
2010/12/21(火) 01:22:26ID:???v5.8.8 built for i386-linux-thread-multi
Encode 2.40
0910nobodyさん
2010/12/21(火) 03:00:18ID:???http://blog.livedoor.jp/dankogai/archives/51231739.html
>>906の言うようにbinmodeを使わないのが正解。
utf8::encodeしてfrom_toとかじゃなくて print encode("iso-2022-jp", $x) のほうがいいと思うけど。
0912nobodyさん
2010/12/21(火) 09:05:29ID:???自分でencode関係のモジュール作るときは気をつけろって話じゃないの?
さすがにちぎれたからって結果がおかしくなるようなものが標準添付なのは
どうかと思うな。
0913nobodyさん
2010/12/21(火) 09:35:50ID:???>910
なるほど・・勉強になりました。
0914nobodyさん
2010/12/21(火) 17:40:31ID:???であるかのように振舞うにはどうしたらいいのでしょうか?
0916nobodyさん
2010/12/22(水) 09:00:32ID:???0917nobodyさん
2010/12/22(水) 11:08:37ID:???0918nobodyさん
2010/12/23(木) 10:41:19ID:???1時間ぐらい悩んだわ
0919nobodyさん
2010/12/25(土) 00:42:21ID:???use CGI::Carp qw(fatalsToBrowser);
がうまく動かないんですね。
%test ってだけすると Internal Server Error としか出ず。
use utf8 を外すと
Global symbol "%test" requires explicit package name at test.cgi line 25.
Execution of test.cgi aborted due to compilation errors.
ってちゃんと出る。
むぅ。。。
0920nobodyさん
2010/12/25(土) 01:59:19ID:???0921nobodyさん
2010/12/25(土) 04:32:14ID:???逆になんでブラウザだと表示されないのか、それはそれで疑問がw
0922nobodyさん
2010/12/25(土) 04:48:35ID:???0923nobodyさん
2010/12/25(土) 04:57:06ID:???レス数が900を超えています。1000を超えると表示できなくなるよ。