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

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

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

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

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

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

過去ログやお勧めサイトは >>2-10
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!
0210nobodyさん2005/08/26(金) 13:56:08ID:0igOMeuL
>>203
ありがとうございます!
$body =~ /^([\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])*$/ or chop $body;
↑こっちのやりかたで完璧でした。ShiftJISのままできました。

>>202
うーん。まぁ今となっては確かにeucでやった方がいいのかなぁ?
サイト上でテキスト(HTML)がSJISでCGIだけEUCだとチグハグ感がありますので。
02111832005/08/26(金) 21:24:32ID:???
>>210
SJIS好きでもEUCに慣れた方がいいぞ
俺みたいにならんようにな('A`)
0212nobodyさん2005/08/26(金) 22:01:27ID:???
>>210
出力だけShift_JISにすれば?
0213nobodyさん2005/08/27(土) 11:09:24ID:???
>>211
うーん。そうですよねぇ。真摯に受け止めます。

>>212
それも手間じゃないですか?
そうそう、jcodeを使うと半角が化ける以外に、処理が遅くなるっていうのがありました。
最近はハードのスペックが上がったから問題ないとも思うのですが。
0214nobodyさん2005/08/27(土) 11:54:37ID:???
、ハ、餞JIS、ヌヘ隍�ウ、ネ、ートヒ、キ、ソ、鬘ゥ
2、チ、网簗ムエケ、キ、ハ、、、キ。」
0215nobodyさん2005/08/27(土) 12:25:45ID:???
既出だけど、半角カナが化けるのはjcodeが悪いわけじゃないから。
ロジックが甘いか、工夫が足りないだけ。

EUCだと正規表現で楽できることもあるけど、クライアントのほとんどはSJISの住人だから。
SJISの住人相手にはSJISで組んだほうがメリットになることも多いよ。

そもそも、最近はjcodeの出番がめっきり減った気がする。
0216nobodyさん2005/08/27(土) 13:01:28ID:???
内部処理やスクリプトの文字コードにSJIS使うのは手間増えるだけだから
オススメしないけどな。入り口と出口で変換する方が楽。

中身は古い人はEUCで、イマドキの人はunicodeが良いでしょう。
0217nobodyさん2005/08/27(土) 14:53:32ID:???
Unicode使うとSJISなんて使う気になれなくなるよ
0218nobodyさん2005/08/27(土) 19:10:26ID:???
ならなくなる じゃないか?
0219nobodyさん2005/08/27(土) 19:25:06ID:???
Unicodeってそんなにいいのか?(他のスレで散々既出だと思うが)
grep等のツールが使えなくなるのがちと痛いんだよなぁ。
新しめのLinux環境だと使えるのかな。。?
0220nobodyさん2005/08/27(土) 22:05:10ID:???
Grepの方をどうにかしようぜ
0221nobodyさん2005/08/28(日) 16:08:49ID:???
WinXP、ActivePerl6.8.1です。
use encodingやuse Encodeをソースに記述し起動させると、「問題が発生しました。ご迷惑をおかけして(ry」が出てPerlが強制終了してしまいます。
Encode.pmをコマンドラインで直接立ち上がげても同じでした。
何が原因でしょうか?
0222nobodyさん2005/08/28(日) 16:11:45ID:AszUkSZs
質問させてください。

Encode.pmがインストールされている環境とそうでない環境とで、プログラム内部で処理を分けようと思っているのですが、なぜかうまく行きません。

$Eflag = eval('use Encode qw/ from_to :fallbacks /; 1');

とやっておいて、

if ($Eflag) {
from_to($_, 'utf8', 'cp932', FB_XMLCREF);
}

という風に処理したいのですが、evalを通したらfrom_toだけだとうまくインポートできるのですが、この書き方だと:fallbacksのほうだけインポートされないようです。
普通にevalを通さないで、use Encode qw/ from_to :fallbacks /;と書いたら正常に動くのですが、これだとEncode.pmのない環境ではコンパイル時エラーが出てしまうので困っています。

ここでevalを通すと、:fallbackはインポートされないのでしょうか?
うまく処理する方法または、これに代わる何かいいアイデア等ございましたらぜひとも教えていただきたく思います。
0223nobodyさん2005/08/28(日) 16:50:57ID:???
>>221
とりあえず、アンインストールして、ディレクトリも全部消してから、再インストール。
できれば、最新のバージョンのものを。

>>222
BEGIN{
eval("use Encode qw(:fallbacks from_to)");
$eflag = ($@ ? 0 : 1);
}
if ($eflag){
from_to($d, 'utf8', 'cp932', FB_XMLCREF);
print $d;
}
0224nobodyさん2005/08/28(日) 17:01:40ID:???
>WinXP、ActivePerl6.8.1です。
ここスルーでつか?
0225nobodyさん2005/08/28(日) 17:05:14ID:???
「ここだけ○年進んでるスレ」の類から来たんだろう
0226nobodyさん2005/08/28(日) 18:08:27ID:AszUkSZs
>>223
どうもありがとうございました。
参考にさせてもらったところ無事問題が解決できました。
0227nobodyさん2005/08/29(月) 02:19:20ID:???
すみません質問します。メールを登録アドレスに配信するシステム(メルマガを発行しようと思ってます)を考えているのですが、アドレスが行ごとに入力されているファイルと、実行用のperlを用意して、

$sendmail = '/usr/sbin/sendmail';
open(LOG,"$datfile");
flock(LOG, LOCK_EX);
@alldata = <LOG>;
close(LOG);
foreach $mail (@alldata){
$mail =~ s/ //g;
open(MAIL,"| $sendmail -t");
print MAIL "To: $mail\n";
print MAIL "From: magazine\@foo.co.jp\n";
print MAIL "Subject: bar\n\n";
print MAIL "$message\n";
close(MAIL);
}

メールアドレスが格納されているファイル($datfile)を展開して、各行を$mailに代入(万が一を考えて半角スペースの除去も行っています)して、同じメールを送信しようとしているのですが、送信されるメールは、
差出人:ユーザーID
受信者:$mail該当者
で、本文に、

From: [email protected]
Subject: bar

$messageに入ってる文字列

と出てしまいます。

試しに$mailの部分の記述を実在するアドレスに差し替えたところ、$datafileの行数だけ(その回数だけforeachが実行されるから)記入したアドレスにメールが届きましたが、その場合は、差出人にFrom: の内容が、件名にSubject: の内容が入り、本文にこれらは出ませんでした。

なぜ、ズレが生じるのでしょうか?根本的に理解できてないかもしれません。お教えいただけると幸いです。
0228nobodyさん2005/08/29(月) 02:31:55ID:???
$mail =~ tr/\r\n//d; とでもしとけ。
0229nobodyさん2005/08/29(月) 02:32:27ID:???
SPAM業者はカエレ
0230nobodyさん2005/08/29(月) 02:35:14ID:???
>>228
改行コードが残っていて、改行のみの行が存在し、それ以降が本文扱いにされているのでしょうか。
有難う御座います。早速試してみたいと思います。
0231nobodyさん2005/08/29(月) 02:39:07ID:???
>>228
うまくいきました。有難う御座いました。

>>229
そういう誤解を招くと思ってメルマガと言ったんですが、信用はないですよね。
気分を害してしまい申し訳ありませんでした。
0232nobodyさん2005/08/29(月) 22:53:35ID:2Z/c1c0/
ごめんなさい。自分では解決できないので
質問させて下さい。

perl 5.0 linux apache環境です。(あまり環境は関係ない質問ですが。。)

国語,30,53,23,23
算数,35,35,12,64
公民,43,43,34,56
日本史,33,2,2,2

といった感じのCSVファイルがあったとして一部のデータのみ書き換えるという処理は
可能でしょうか?

つまり80行目の3列目だけデータを書き換えるとか、公民の5列目(56の部分)だけ56を52にするとか
することは可能でしょうか?

私の知識では
このCSVをすべて@配列にいれてこれをforeachで一行一行読んで5つにカンマでsplitして変数に保存していき、

($date.=date[0].",".date[1].",".date[2].",".date[3].",".date[4]."\n" )

date[0]が公民だったら4行目を52にして

($date.=date[0].",".date[1].",".date[2].",".date[3].",52\n" )

$dateを print FILEHANDLE date.csv;

ですべて上書き保存するという非効率な方法しか思いつきません。

要所部分だけ書き換えるという方法がありましたら、ないかも知れませんが。。
教えていただければ幸いです。
0233nobodyさん2005/08/29(月) 23:02:38ID:???
>>232
その環境でDB使わないで、あくまでcsvで行くのですね…。

すべて配列に入れるよりも、
正規表現で「公民」にマッチする行だけsplitして書き換えては。
0234nobodyさん2005/08/29(月) 23:06:26ID:???
>>232
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq5.html#How_do_I_change_one_line_in_a_fi
http://www.rfs.jp/sitebuilder/perl/05/func/join.html
02352322005/08/29(月) 23:36:34ID:2Z/c1c0/
>>233

ありがとうございます。mysqlもpostgreも使えない環境です。。
仰るとおりの方法にしたいのですが、
splitして該当の行だけ書き換えるという処理がわかりません。
もしよろしければ、ヒント下さい。

>>234

ありがとうございます。
読んでみましたが、私が232で試そうとしている
方法のようです。確かにこれが一番簡単で
私のような初心者にもわかりやすいのですが、
書き換える箇所が何箇所もあると
同じファイルを1回の処理で何回も上書き保存しないと
いけない重たい処理になってしまいます><
0236nobodyさん2005/08/29(月) 23:36:40ID:???
>>232
扱うファイルが小さいなら、DBを使うよりも
現在のようにシーケンシャルファイルを扱う方法のままが手軽でいいかも。

その上で、
1. 2次元の表を扱うので2次元配列に読み込む
2. ファイルからの読み込み、ファイルへの書き出しは
 push, join, map 等を使って簡潔に書けるので、その辺りを調べてみる
といいと思う。

my @data;
open(IN, 'data.csv');
for (<IN>) {  # ファイルサイズが大きいなら while で
  push(@data, [ split(/,/) ]);
}
close(IN);

$data[79][2] = 'hoge';  # 80行3列を書き換える
$data[2][4] = 52;  # 公民の5列目を52に

open(OUT, '> data.csv');
print OUT map { join(',', @{$_}) . "\n" } @data;
close(OUT);

# チェックしてないのでミスありそう

こんな感じはどうでしょう?
0237nobodyさん2005/08/29(月) 23:39:03ID:???
つStorable
02382322005/08/30(火) 00:03:14ID:x5m98we0
>>236

ありがとうございます。
その方法でやってみます。
確かめていないのでうごくかはわかりませんが、
取次ぎお礼まで!
ありがとうございました。
0239nobodyさん2005/08/30(火) 01:18:03ID:???
宿題くさいな
0240nobodyさん2005/08/30(火) 11:27:34ID:???
>>237
とか、テキストにしときたいなら Data::Dumper とかのほうが簡単
0241nobodyさん2005/08/31(水) 14:49:41ID:2aj3BZHt
変数のサイズを知りたい時は何を使えばいいんでしたっけ?
0242nobodyさん2005/08/31(水) 14:56:42ID:???
すいません、思い出しました。lengthでした。
0243nobodyさん2005/08/31(水) 16:24:59ID:???
ソースの中に
-----
next if (!$acl{$base_remote_user,$minfo->{'dir'}} &&
!$acl{$base_remote_user,"*"});
-----
という箇所があったのですが、中括弧($acl{})の中の意味が分かりません。
中括弧でかこって中にカンマというのはどういう意味でしょうか?
0244nobodyさん2005/08/31(水) 16:38:21ID:???
>>243
多次元配列のエミュレーション用の機能で
$foo{$a,$b,$c}
は
$foo{join($;, $a, $b, $c)}
と同じ。詳しくはperlvar(1)の$;の項などを参照されたい。
0245nobodyさん2005/08/31(水) 18:22:07ID:???
文字(A,a)をコード(\x41,\x61)に変換したいのですがどのようにすればいいでしょうか?
また、逆にコードを文字に戻したりもしたいのです。
0246nobodyさん2005/08/31(水) 18:23:01ID:???
ageます
0247nobodyさん2005/08/31(水) 18:30:58ID:???
>>245
pack、unpack、ordあたり調べてきな。
# 実際に '\x' も付けて表記してるならevalで戻せるけどな。
02482432005/08/31(水) 18:46:38ID:???
>>244さん
なるほど、分かりました。
どうもありがとうございました。
0249nobodyさん2005/08/31(水) 19:01:48ID:???
>>245
あまりきれいに書けてないけど。例を。

for ('A', 'a') {
  print '\x' . unpack('H2', $_);
}
for ('\x41', '\x61') {
  /\\x(..)/;
  print pack('H2', $1);
}
0250nobodyさん2005/08/31(水) 19:11:24ID:4hPwGNyx
XMLRPC::Liteを使ってブログにを投稿しようとしてるんですが
日本語使うと文字化けしちゃって読めません。
# どうやらbase64に強制変換されてる様子。
どうすれば日本語を使えるようになるでしょうか。
なお現在のソースはイカの感じです。

use strict;
use XMLRPC::Lite;
use Jcode;

my $name = "name";
my $pass = "pass";
my $title = "たいとる";
my $description = "ほんぶん";

#&Jcode::convert(\$title,'utf-8');
#&Jcode::convert(\$description,'utf-8');

print $title;

my $msgresult = XMLRPC::Lite
-> proxy('http://blog.fc2.com/xmlrpc.php')
-> call('metaWeblog.newPost', "0", $name, $pass,
{
'title' => $title,
'description' => $description,
'mt_allow_comments' => 1, # must be int, not string
'mt_allow_pings' => 1 # must be int, not string
},
1
)
-> result;
0251nobodyさん2005/08/31(水) 21:12:32ID:HyyIksuT
ほんとに初歩的な事だと思うんですが…
if( $a == 0 || $a == 1 || $a == 2 || $a == 3 ){

$aに0、1、2、3のどれかが入っていたら…、という文なんですが、
これをもう少し簡潔に書くとどうなるでしょうか?
数字が0、1、2、3……10くらいまで続き、また別のグループで11〜20、21〜30までを
今はそれぞれelsifで処理しています。
効率が悪いかな?と思いまして…。よろしくお願いします。
0252nobodyさん2005/08/31(水) 21:19:36ID:ihFBKKnR
>>251
TIMTOWDI

if $a =~ /(\d+)/ and 0 <= $1 and $1 <= 30
if defined $a and 0 <= $1 and $1 <= 30
0253nobodyさん2005/08/31(水) 21:19:58ID:???
>>251
if ( 0 <= $a && $a <= 10 ) { }
elsif ( 11 <= $a && $a <= 20 ) { }
elsif ( 21 <= $a && $a <= 30 ) { }
0254nobodyさん2005/08/31(水) 21:24:22ID:???
>>251
書き方云々ではなく、その処理自体を何とかできんのか
02552512005/08/31(水) 22:24:49ID:???
レスありがとうございます!
>254
すみません、なんかこの処理を他に変える方法が今の自分にはわからなくて…
スキル不足ですね。勉強します。
■ このスレッドは過去ログ倉庫に格納されています