トップページ⇒php
1001コメント371KB

Perlコーディング初心者質問スレ Part 43

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2005/08/12(金) 01:26:47ID:mHnZWvqz
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0109nobodyさん2005/08/23(火) 09:47:32ID:???
>>108
>>102 です。
どうも元のコード読む限り、置換は一ヶ所だけなんだよね。elsif で繋いであるし。
正規表現の作製コストと、splitかけてjoinするコスト
どっちが良いかは、この場合かなり微妙…。もしかしたらsplit, joinのが安いかも。
0110nobodyさん2005/08/23(火) 12:04:31ID:???
>>109
最近見かけた名言を贈ろう。

 「推測するな。計測しろ」

http://search.cpan.org/~nwclark/perl-5.8.7/lib/Benchmark.pm
0111nobodyさん2005/08/23(火) 12:40:05ID:???
説教するな、説得しろ。
0112nobodyさん2005/08/23(火) 13:46:44ID:???
my @hoge = ('a', 'b', 'c');
my @moge = (1, 2, 3, 4);
my @foo = (\@hoge, \@moge);

@fooを使って、$hoge[2]の値を取得するにはどうすればよいですか?
\@hogeは必ず$foo[0]にあります。
0113nobodyさん2005/08/23(火) 13:57:40ID:???
>>112
http://perldoc.jp/docs/perl/5.6.1/perllol.pod
http://www.kt.rim.or.jp/~kbk/perl-5.8/perlreftut.html
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlref.html
01141082005/08/23(火) 14:42:04ID:???
>>109
一回だったら微妙かもですね。

>>110
ベンチなら正規表現の方が2倍速かった。(@hourlist=10で計測)
ただ、ベンチは繰り返し実行するから、
正規表現のコンパイルコストなど測れない部分がある。
大抵は無視できるけど、一回こっきりの話だと無視できない可能性も。
細かい話だけどね。
01151022005/08/23(火) 17:55:10ID:???
>>110
ありがとう。その通りです。
ベンチ鬼のようにやってたから、目測でコスト見積るようになった。
「スカラ変数宣言で◯バイト消費。数値入力でヘッダ部分にビットが立つ。ボディーが追加されて数値設定。文字列として使っちゃったから、ヘッダ部のビット変更。ボディーの数値構造体切り離して、両用の構造体に変更。」
とか、気にしてた頃はスクリプト見ながらここまで考えてた(あほです)。

>>114
わざわざベンチありがとう。やっぱり1回だと微妙ですよね…。m/<>/go がリニアサーチだし。
0116nobodyさん2005/08/23(火) 21:09:27ID:???
IE限定だけどJavaScriptでクリップボードの内容をコピーできるので、
そこら中のサイトで「セキュリティーホールだ!クリップボードの内容が盗見られる!」
と騒ぎ立ててんだけど、もちろんsubmit送信を使えば値を渡すことができるだろうけど、
1回の閲覧のみでJavaScriptで取った値をCGIに渡すことは不可能だよね?
0117nobodyさん2005/08/23(火) 21:14:43ID:???
カンマ区切りのデータから、必要な要素を取り出す方法を教えていただきたいです。

太郎,男,20才
花子,女,21才
健太,男,22才
 ・
 ・
というデータがname.datというファイルでcgiと同じディレクトリにあり、
パラメータとして'健太'を与えてやると、'22才'と返ってくるようなスクリプトは、どう書けばいいのでしょうか。
よろしくお願いします。
0118nobodyさん2005/08/23(火) 21:22:48ID:???
open IN, 'name.dat';
while (<IN>) {
 chomp;
 my @tmp = split /,/;
 $name2age{$tmp[0]} = $tmp[2];
}
close IN;
print $name2age{'健太'};
ハッシュのキーに漢字ってキモいな
0119nobodyさん2005/08/23(火) 21:28:56ID:???
kenta -> '健太'
みたいなハッシュを別に作って解決

(゚∀。)アリャ?
0120nobodyさん2005/08/23(火) 21:49:40ID:???
>>118
>>119
ありがとうございます。試してみます。
0121nobodyさん2005/08/24(水) 01:00:02ID:???
>>116
できるよ。
でもそれがセキュリティホールになるのかどうかは知らない。
0122nobodyさん2005/08/24(水) 01:04:27ID:???
>>116
面白そうだね。やってみようかな。
0123nobodyさん2005/08/24(水) 01:11:31ID:???
クリップボード覗いて何が楽しいんだ?
0124nobodyさん2005/08/24(水) 01:11:32ID:???
onLoadでページ開いた瞬間に別窓へsubmitして即閉じるとか?
いずれにせよバレバレっぽいなぁ
0125nobodyさん2005/08/24(水) 01:12:47ID:???
>>124
XMLHttpReq略 ならバレバレではないけど。
できるけど、何? って感じ。
0126nobodyさん2005/08/24(水) 01:16:54ID:???
今流行りのajaxだにゃん。
0127nobodyさん2005/08/24(水) 04:39:31ID:???
>>116
板違い。
http://pc8.2ch.net/test/read.cgi/sec/1005185421/
0128nobodyさん2005/08/24(水) 05:33:37ID:???
質問です。
PCからは書き込みができるのですが携帯(�@モード)からは書き込みはおろか管理画面へすら入れません。
CGI本体のソースはこちらになります。
http://namihei.zone.ne.jp/upup/up/44694.txt
他にはlogファイルとjcode.plを使います。
enctype="multipart/form-data"あたりに問題があるように思うのですが行き詰まってしまいました。
どこをどのようにすれば携帯から書き込めるようになるでしょうか?
01291282005/08/24(水) 05:37:30ID:???
すいません。直接リンクだと403になってしまうようです。
ttp://namihei.zone.ne.jp/upup/up/44694.txt
0130nobodyさん2005/08/24(水) 06:19:55ID:???
>>128
原因わかってるならenctype="multipart/form-data"を消せばいいやん
それはファイル添付するときのenctypeだし
どうしてもenctype書きたいならenctype="x-www-form-urlencoded"で
0131nobodyさん2005/08/24(水) 07:33:16ID:???
>>128
マルチかよ答えるんじゃなかった
氏ね市ね詩ね氏ね市ね詩ね氏ね市ね詩ね氏ね市ね詩ね氏ね市ね詩ね氏ね市ね詩ね
01321282005/08/24(水) 07:58:30ID:???
>>130
サンクスコ
0133nobodyさん2005/08/24(水) 08:47:43ID:???
$res[131] = new m9('a')->pugyaaa();
0134nobodyさん2005/08/24(水) 09:45:36ID:???
cat unko*.txt > unkofile.txt と同じことをperlでどういう風に書いたらいいでしょうか?
ファイルを開いて読んで配列に入れてから書き込むを永遠と繰り返すしかないんでしょうか。
0135nobodyさん2005/08/24(水) 11:03:29ID:???
>>134
#!/usr/bin/perl
`cat unko*.txt > unkofile.txt`;
0136nobodyさん2005/08/24(水) 11:04:23ID:ephPxiIZ
unko.txt
0137nobodyさん2005/08/24(水) 11:15:53ID:???
外部プログラムは一切使えない(インストールされていない)ので
他の方法お願いします。
0138nobodyさん2005/08/24(水) 11:24:30ID:???
>>134
ファイルを開いて書き込むのを繰り返すのが普通。ただし
配列に入れるのは無駄なので読んだらどんどん書き出せ。
.
0139nobodyさん2005/08/24(水) 11:44:21ID:???
>>138
ありが�d できますたっ
0140nobodyさん2005/08/24(水) 13:14:34ID:???
>>134 >>139
解決したみたいだが

perl -pe "" unko*.txt > unkofile.txt
0141nobodyさん2005/08/24(水) 15:15:16ID:???
投票システムを作ろうとしているのですが、アドバイスお願いします。
パラメータ$goodsnumに入れた商品番号$tmp[0]に対する得票数$tmp[1]を
カウントアップさせたいのですが、ログファイルがうまく更新されません。
コードは以下の通りです。

open(LOG, "+<$file");
flock(LOG,2);
print "Content-type: text/html\n\n";
while ($line = <LOG>) {
 @tmp = split /,/,"$line";
 if ("$tmp[0]" eq "$goodsnum"){
   seek(IN,0,0);
   $tmp[1] ++;
   print LOG "$tmp[0],$tmp[1]\n";
   truncate(IN,tell());
   print "商品番号$tmp[0]の得票数は$tmp[1]";
 }
}
flock(LOG,8);
close(LOG);

期待する結果(ログファイルの内容)
実行前 syohin555,0 → 実行後 syohin555,1

実際の結果(ログファイルの内容)
実行前 syohin555,0 → 実行後 syohin555,0[改行]syohin555.1

ログファイルには他にも商品の投票データがあり、パラメータで渡した商品のみ、カウントアップさせる企てです。
ごちゃごちゃして申し訳ありません。どうぞよろしくお願いします。
0142nobodyさん2005/08/24(水) 15:23:02ID:???
>>141
> seek(IN,0,0);
> truncate(IN,tell());
INって何。
0143nobodyさん2005/08/24(水) 15:28:01ID:???
>>142
あ!すみません。そこも'LOG'です。
もうしわけございませんでした。
0144nobodyさん2005/08/24(水) 15:56:30ID:???
>>141
一行の長さが不定なテキストデータを、読み出しながら書き出すのは無茶。
得票数が 9 => 10 になったらまずいよね。
全部読み込んでから全部書き出すのが無難じゃないかな。
0145nobodyさん2005/08/24(水) 16:05:56ID:???
>>141
>ログファイルには他にも商品の投票データがあり
おいおい、だめじゃん
0146nobodyさん2005/08/24(水) 16:10:26ID:???
seekもtruncateもwhileの外でやらないとね。
chomp;がないのに¥nつけると改行だけ増える罠。
根本的に流れがおかしい希ガス。
01471412005/08/24(水) 16:15:29ID:???
どうも無茶なことをしてるようですんません。
なんとか頑張ってみます(; ;)
01481412005/08/24(水) 17:33:40ID:???
駄目ですorz
大まかな構想を練っているのですが、アドバイス頂けますでしょうか。

1.ログファイルを開く
2.改行で切り分けて@ary1にいれる
3.$ary1[0],[1],[2]...をそれぞれカンマで切り分けて@ary2に入れる
4.whileを使って$ary2[0]がパラメータに合致するノードを探す
5.見つかったら$ary2[1]をカウントアップ。
6.@ary1をログファイルに上書きする

こんな感じでしょうか?
頭が爆発しそうなのでよろしくお願いします。
0149nobodyさん2005/08/24(水) 17:43:24ID:???
>>148
大まかな流れはそんな感じで良いと思う。
あと、得票数のデータは配列にするんじゃなくてハッシュにするとやりやすいと思う。
01501412005/08/24(水) 17:51:17ID:???
>>149
ハッシュですか。調べてやってみます。
ありがとうございました。
0151nobodyさん2005/08/24(水) 18:00:22ID:???
・ログファイル開く
・foreachかwhileで一行ずつ読み込む
・カンマで区切り、それぞれを変数で区切る
・最初の要素とパラメタが一致すれば、最後の要素をインクリメント
・3つの変数をカンマ区切りで配列に
・処理終了後、配列をログファイルに上書き

じゃだめなのか
0152nobodyさん2005/08/24(水) 18:02:50ID:???
適当で動くかわからないけど、流れを理解するため重視で。

open(LOG, "+<$file");
print "Content-type: text/html\n\n";
while (<LOG>) {
chomp;
@tmp = split /,/;
if ($tmp[0] eq $goodsnum){ $tmp[1] ++; }
push(@txt, "$tmp[0],$tmp[1]\n");
print "商品番号$tmp[0]の得票数は$tmp[1]";
}
seek(LOG, 0, 0);
print LOG @txt;
truncate (LOG, tell(LOG));
close(LOG);

ファイルの内容を丸まる配列に入れちゃうのは初心者の処理だけど、まぁ後は理解して改造してくれ。
01531412005/08/24(水) 18:13:54ID:???
ででで、でキタ━━━━(゚∀゚)━━━━ッ!!と思う。
もう丸一日かまってるから混乱してきた。
最終的なコードはこうなりました。
みんなありがとう!

@ary = ();
open(LOG, "+<$file");
flock(LOG,2);
print "Content-type: text/html\n\n";
while ($line = <LOG>) {
 chomp($line);
 @tmp = split /,/,"$line";
 if ("$tmp[0]" eq "$goodsnum"){
  $tmp[1] ++;
  push(@ary,"$tmp[0],$tmp[1]\n");
 }else{
  push(@ary,"$tmp[0],$tmp[1]\n");
 }
}
seek(LOG, 0, 0);
print LOG @ary;
truncate (LOG, tell(LOG));
flock(LOG,8);
close(LOG);

>>151
>>152
ありがとうございます。
今から確認してみます。
0154nobodyさん2005/08/24(水) 19:59:02ID:???
変数に入った条件式を使ってif文って作れませんか?

例えば、こんな感じで。

$opt = "or";
print "OR : OK" if(1 == 1 $opt 2 == 1);

$opt = "and";
print "AND : OK" if(1 == 1 $opt 2 == 1);

[表示結果]
OR : OK
0155nobodyさん2005/08/24(水) 20:02:21ID:???
eval
01561542005/08/24(水) 20:09:36ID:???
>>155
$opt = "or";
print "OR : OK" if(1 == 1 eval($opt) 2 == 1);
としても、

$opt = "or";
print "OR : OK" eval(if(1 == 1 $opt 2 == 1));
としても、正常に動かないのですが・・・

evalつけるところ間違えてます・・・?
0157nobodyさん2005/08/24(水) 20:23:46ID:???
>>156
$opt = "or";
eval "print 'OR: OK' if 1 == 1 $opt 2 == 1";
0158nobodyさん2005/08/24(水) 20:31:32ID:???
>>154-157
if eval "1 == 1 $opt 2 == 1";
01591542005/08/24(水) 20:59:12ID:???
>>158
サンクス
うまくいきました。
01601542005/08/24(水) 21:58:28ID:???
すいません、もひとついいですか?

evalを使うことで、演算子の変数を展開して条件分岐してくれるようにはなったんですが、
演算子以外の変数が合った場合、なぜか上手く動作しません。

$data1 = "hogehoge";
$data2 = "foofoo";
$ptn1 = "hoge";
$ptn2 = "boo";
$opt = "or";

print "OK" if( eval"($data1 =~ m/$ptn1/) $opt ($data2 =~ m/$ptn2/)" );

欲しい結果は当然、OKです。
0161nobodyさん2005/08/24(水) 22:02:14ID:???
>>154
ダブルクオテーション囲んでるから、evalが解釈するのは
hogehoge =~ m/hoge/ or ...
になってる。
0162nobodyさん2005/08/24(水) 22:04:18ID:???
>>160
$data1, $data2 の頭にバックスラッシュ入れて変数展開抑制
0163nobodyさん2005/08/24(水) 22:06:32ID:???
試しにeval()にしてみたんですが、やっぱり動きませんorz
0164nobodyさん2005/08/24(水) 22:09:12ID:???
>>162
ありがとう!
0165nobodyさん2005/08/24(水) 22:16:54ID:???
>>164
eval じゃなくて printした時にどういう文字列になってるか
考えるなり確認した方が良いよ。
0166nobodyさん2005/08/24(水) 23:13:17ID:PXiCgge7
質問させて下さい。

csvを読み込んで、表示するというプログラムを
書いていますが、データはShift_JISなので
Shift_JisをUTF-8に変換したいです。

ネットで調べるとJcode.pmが必要と書いてありました。
早速使ってみたところ、私が使っているサーバは
標準モジュールすら入っていないサーバなので
Jcode.pmだけいれてもダメでした。

そこで、友人のサーバでやろうと思っていますが
友人のサーバはperl5.0なんとかで
結構古いです。標準的なモジュールは入っています。

そこで質問です。

�@この環境にJcode.pmファイルだけ置けばうごくように
なりますか?
�AJcode.pmを置く事で他のperlプログラムが動かなくなったりしますか?
�BJcode.pmを置いてうごいたとして、shift_jisのまま表示するのと
  UTF8に変換してから表示するのでは、処理のスピードに大きな
  違いがでますか?

自己解決不可能だったため。。おねがいします。。orz

0167nobodyさん2005/08/24(水) 23:23:23ID:???
Jcodeは5.4以上必要だった気がする。

にしても5.0はねぇだろ。ちゃんと調べろ
0168nobodyさん2005/08/24(水) 23:52:46ID:???
お前もうjcode.plでいいよ
0169nobodyさん2005/08/24(水) 23:55:26ID:???
もしくは nkf -w
0170nobodyさん2005/08/25(木) 00:08:57ID:PZEhiYYs
>>168
jcode.plはUTF-8未対応

分かってて書いてると思うがw
0171nobodyさん2005/08/25(木) 01:32:53ID:???
Perl5.6以上にするのが一番の早道
0172nobodyさん2005/08/25(木) 08:22:01ID:???
>>166
1. コピーで突っ込んだことが無いので、よく分からないけど、
最低でもJcode::*の辺りも必要だと思う。
2. それは無い。
3. UTF-8変換すると、かなり遅くなるはず。

telnet/sshが使える環境なら、そっちからきちんとインストールしたほうがいい。

>>167
5.004から動くはず。
5.005_03で動作してるよ。
0173nobodyさん2005/08/25(木) 15:17:31ID:???
>>166
そもそも166が使ってるサーバのPerlのバージョンがわからんと話にならん。
さらにサーバ会社も晒せば同じ環境に居る人が答えてくれるかもしれん。
0174nobodyさん2005/08/25(木) 16:09:06ID:???
>>167
>にしても5.0はねぇだろ。
「5.4」も酷いぞ。

>>171
5.8.1 以上の間違いだろう。

>>173
「標準モジュールすら入っていないサーバ」は @nifty (@homepage) の
別名と考えていいかと。そうなら 5.004 だか 5.005 だかその辺だったと思う。

>>166
他にもこういう選択肢もある。
http://search.cpan.org/~hio/Unicode-Japanese-0.27/
0175nobodyさん2005/08/25(木) 17:18:03ID:???
すみません、Activeperlの5.8.7で、WindowsXPの日本語フォルダを扱いたいのですが、
Encodeでいろいろやってみたもののうまくいきませんでした。

例えば、
while(<c:/bin/jane/Logs/2ch/ネット関係/WebProg/*.dat>) { }
みたいに、あるフォルダの下の全ファイルをさらうとかしたいのですが、
日本語が含まれているとうまくいきません。

どうすればよいのか、お願いします。
0176nobodyさん2005/08/25(木) 18:01:49ID:???
175追記
シフトJISでスクリプトを書くと、
use encoding "shiftjis";
を入れるとうまくいかず、入れないとうまくいきます。
(ただし、それを入れないと今度は他の日本語を扱う部分がおかしくなってしまいます)
0177nobodyさん2005/08/25(木) 18:14:31ID:???
>>175
>>13
0178nobodyさん2005/08/25(木) 18:28:37ID:???
>>177
そこを読んでいろいろ試してみたのですが…
0179nobodyさん2005/08/25(木) 19:02:49ID:ZmEBADhu
長文だった場合、ある長さに区切るようなことをしたいんだけど
↓こんな感じ

こんにちは、Perlスクリプトについて質問があり・・・[長文のため省略しました。続きはこちら]

↑こんな感じで文章を省略したいんですけど、
区切ったバイトが2byte文字か判定する方法ってありませんか?現状文字化けしてます。。。
0180nobodyさん2005/08/25(木) 19:47:47ID:???
>>179
>>11 のテクニックの項とか >>13 とか。
0181nobodyさん2005/08/25(木) 19:57:49ID:???
>>179
$str= = Jcode->new($str)->jfold($width);
で\n区切り。ただし途中の\nは無視する。
0182nobodyさん2005/08/25(木) 20:00:24ID:???
use Jcode;
$st = Jcode->new($str)->jfold($width);

な。
0183nobodyさん2005/08/25(木) 20:24:33ID:???
超メンドくさいやり方

$char_count = 10;
$body = "こんにちは、Perlスクリプトについて質問があります。";
$ascii = '[\x00-\x7F]';
$twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
$threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
@chars = $body =~ /($ascii|$twoBytes|$threeBytes)/og;
for ($count = 0; $count < $char_count; $count++) {
 $str .= $chars[$count];
}

$strは「こんにちわ、Perl」となる
メンドくせ
0184nobodyさん2005/08/25(木) 20:47:01ID:ZmEBADhu
>>181,>>182
レスありがとうございます。自分はjcode使ってないのですが、それでうまくいくのなら試してみたいと思います。

>>183
この手のやり方を求めていました。
実際にやってみたのですが、うまくいきませんでした。
Shift-JIS限定のプログラムなのですが、Shift-JISではどのようにして日本語のフラグを立てているのでしょうか?
色々と検索しているのですが見つかりません。
0185nobodyさん2005/08/25(木) 20:48:56ID:???
eucで
0186nobodyさん2005/08/25(木) 20:49:51ID:???
>>184
文字列はEUC前提。
この場合なら、一回jcodeで$bodyをEUCに変換してから。
で、$strが完成したら、それをSJISに戻せば解決
0187nobodyさん2005/08/25(木) 20:57:13ID:???
$str =~ /^([\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])*$/ or chop $str;
0188nobodyさん2005/08/25(木) 20:57:34ID:???
use encoding 'Shift-jis';
でsjisでも正規表現がうまく動くと聞いているが俺は試してない。
だとしても>>183並にめんどくさいルーチンを通さなきゃいけない。
出力する文字コードがsjis固定でよいのなら

use Jcode;
$str = Jcode->new($str)->jfold($width)->sjis();

だ。
0189nobodyさん2005/08/25(木) 20:59:29ID:???
ちなみに<br>の場合、

$str = Jcode->new($str)->jfold( $width, "<br>" )->sjis();

だ。
0190nobodyさん2005/08/25(木) 21:47:57ID:ZmEBADhu
うーん・・・eucですかぁ・・・
ところで、jcode通すと、半角カタカナが文字化けしますよね?
0191nobodyさん2005/08/25(木) 22:06:41ID:???
&jcode::convert (\$str, "euc");
とかだけだと文字化けするケースがある
&jcode::convert (\$str, "euc", "sjis");
のように、変換前の文字コードを渡すことで解決できる場合もある
0192nobodyさん2005/08/25(木) 22:37:57ID:ZmEBADhu
>>191
なるほど!
0193nobodyさん2005/08/25(木) 22:47:27ID:???
>>187が無視されている件について
0194nobodyさん2005/08/25(木) 22:49:28ID:???
>>175
スクリプトの文字コードをShift_JISにするか、
そのフォルダを示す文字列の文字コードをShift_JISに変換する。
01951932005/08/25(木) 22:58:37ID:???
あ、自作自演に突っ込みいれちゃってたらごめん。
01961872005/08/25(木) 23:29:04ID:???
わざわざ名乗り出るのも何だが俺は別人な。
01971972005/08/25(木) 23:39:21ID:???
俺は ROM ってた
01981932005/08/26(金) 00:10:46ID:???
>>196
うん、ごめん、了解してる。

どうでもいいけど、質問者は回答に何らかのリアクション取って欲しい。
「ワケワカラン(AA略」とかでもいいからさ、
と思う初秋の夜。


回答者たち、お疲れさま。

>>197もおつ。
01991752005/08/26(金) 01:24:12ID:???
>>194
ありがとうございます。
とりあえず下のような感じでうまくいきました。
スクリプトはシフトJISで書いています。


use encoding "shiftjis";
use Encode qw/ encode decode /;

$dir = "c:/bin/jane/Logs/2ch/ネット関係/WebProg";

opendir(DIR, encode("shiftjis", $dir));
@a = readdir(DIR);
closedir(DIR);
foreach(@a) {
  $file = $dir . "/" . $_;
  if($file =~ /dat$/) {
    open(FILE, encode("shiftjis", $file));
    while(<FILE>) {
      $line = decode("shiftjis", $_);
      if($line =~ /回答/) {
        print $line;
      }
    }
    close(FILE);
  }
}

もっとスマートな書き方があればいいんですが…。
0200nobodyさん2005/08/26(金) 04:12:47ID:0igOMeuL
>>193
?>>187は何に使うんでしょうか?
0201nobodyさん2005/08/26(金) 04:16:07ID:0igOMeuL
>>191
ところで、jcodeを通すと半角カタカナが文字化けする件ですが、”場合もある”ということは、やっぱり完全解決は無理っぽいですね。
商用のサイトではどのようにやってるんでしょう?半角カタカナを使いつつ、日本語を省略しているサイトをよく見ます。
0202nobodyさん2005/08/26(金) 04:25:58ID:???
なんでeucで書かないのかなぁ〜
0203nobodyさん2005/08/26(金) 07:19:22ID:???
>>199
Shift_JISで書くなら、直接
while(glob('c:/bin/jane/Logs/2ch/ネット関係/WebProg/*.dat')) {}
でいけない?

>>200
$count = 45;
$body = "こんにちは、Perlスクリプトについて質問があります。";
$attention = "…[長文のため省略しました。続きはこちら] ";
if (length($body) > $count){
$body = substr($body, 0, $count);
$body =~ /^([\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])*$/ or chop $body;
$body .= $attention;
}
print $body;
0204nobodyさん2005/08/26(金) 07:20:33ID:???
>>201
みんながjcode.pl使ってるわけじゃないし。

use String::Multibyte;

$mbcs = String::Multibyte->new('ShiftJIS');
$count = 22;
$body = "こんにちは、Perlスクリプトについて質問があります。";
$attention = "…[長文のため省略しました。続きはこちら] ";
if ($mbcs->length($body) > $count){
$body = $mbcs->substr($body, 0, $count). $attention;
}
print $body;

--
use encoding qw(shiftjis);

$count = 22;
$body = "こんにちは、Perlスクリプトについて質問があります。";
$attention = "…[長文のため省略しました。続きはこちら] ";

if (length($body) > $count){
$body = substr($body, 0, $count). $attention;
}
print $body;
0205nobodyさん2005/08/26(金) 07:35:48ID:???
それと、jcode.plが自動判別で文字化けする主な原因は、
jcode.plがShift_JISの定義を厳密に行っている(半角カナを含めない)からで、
入力側の文字コードを指定してやれば問題ないはず。
0206nobodyさん2005/08/26(金) 09:10:00ID:???
質問です。

JavaScript の escape 関数でエンコードされた文字列
(%uXXXX形式)を Perl でデコードしようとしています。
次のようにやると全てマルチバイト文字の場合はうまくいくのですが、
半角文字が入っているとうまくデコードできないようでした。

use Jcode;

$a = '%u3042%u3044%u3046%u3048%u304A'; # あいうえお
$b = '%u3042a%u3044b'; # あaいb

$a =~ s/%u([a-fA-F0-9]{4})/pack('H4', $1)/ge;
$b =~ s/%u([a-fA-F0-9]{4})/pack('H4', $1)/ge;

print Jcode::convert($a, 'euc', 'ucs2'), "\n";
# あいうえお と表示されOK
print Jcode::convert($b, 'euc', 'ucs2'), "\n";
# あ豹? と表示される。a以降文字化け

環境は、Linux, Perl 5.8.4, Jcode.pm 0.88 です。
Windows, ActivePerl 5.8.6, Jcode.pm 0.86 の環境で出力を sjis に
変えても同じでした。

Jcode.pm で変換できる方法はありますでしょうか?
Encode等、他の方法でもありましたらよろしくお願いします。
0207nobodyさん2005/08/26(金) 10:23:29ID:???
>>206
$bが正しいucs2じゃないからじゃないだろうか。

$b = '%u3042%u0061%u3044%u0062'; # あaいb

となるはずだと思うのだが。
0208nobodyさん2005/08/26(金) 10:57:46ID:???
207のように%u0061等と書く以外に、%u〜以外の1バイト文字に
\x00を補う方法も考えられる。ブラウザなどからその形で送られて
くるので手出しできないとするとこの方法の方がいいかもしれん。

$b =~ s/(?:%u([a-fA-F0-9]{4})|(.))/($1 ne '')? pack('H4', $1): "\x00$2"/ge;
02092062005/08/26(金) 11:46:38ID:???
>>207 >>208
ありがとうございました。うまくいきました。

正しいucs2ではなかったのですね。
アドバイス通り修正することで、Jcodeによる文字コードの
自動判別も使えるようになりました!

print jcode($b)->euc, "\n"; # OK!
■ このスレッドは過去ログ倉庫に格納されています