トップページ⇒tech
1001コメント344KB

Perlについての質問箱 28箱目

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/10/31(火) 14:52:21
"The duct tape of the Internet" こと、Perlについての質問箱です。
"There's more than one way to do it" ということで、Perlの奥深さについて皆で語り合い、追求してまいりましょう。

CGIについての質問は板違いです。WEBプログラミング板でどうぞ。
CGIとPerlの区別がつかない人もWEBプログラミング板に行ってください。
(WEBプログラミング板 http://pc8.2ch.net/php/ )

CGIの質問は答えがPerlと全然関係ない話に帰着する場合が多かったりするのでWEBプログラミング板に行って聞いたほうが得ですよ。
このスレでは(CGI以外の)純粋にPerlのみに関係する質問を取り扱っていこうと思います。
スレ違いの質問にはスルーか、速やかな誘導をお願いします。

http://www.perl.org/get.html
● 2006/10/31現在の最新版: 5.8.8
● 2006/10/31現在の開発版: 5.9.3

前スレ
Perlについての質問箱 27箱目
http://pc8.2ch.net/test/read.cgi/tech/1157874614/

リンク集は>>2-3
過去スレは>>4
0052デフォルトの名無しさん2006/11/01(水) 22:16:51
>>50
日本人だけが使ってるわけじゃないからね。
そもそもEncode関連はサイズ大きいから、必要としていない言語圏の方々からは嫌われてるとか聞いたこともあるし。

それにEncodeを使えば簡単にEncode::EUCJPMSみたいなのが作れるんだから、他言語よりはマシな気がする。
0053デフォルトの名無しさん2006/11/01(水) 23:37:58
本当に困っています。
行はいいのだが、列としてのあつかおうとすると
非常にめんどう(表計算ファイルとかのとき致命的)
たとえば2次元配列のリファレンス
$ref = ([ ],[ ], [ ])
があるとするとこれのそれぞれの
要素の第一成分を表示する
簡単な方法はないでしょうか?
print @{$・・@$ref->[0]};
といったかんじでできない?
0054532006/11/01(水) 23:44:18
いままで思いついた
簡単な方法は

foreach (@$ref){
print $$_[0];
}

ぐらいでもこれでもforeachとかかませて色々操作する必要がある
特に列間の計算とかすることになるとこれでは非常に
面倒
なにか一単語で簡潔にあらわせる方法があったはずなんだが・・・
おもいだせない
0055デフォルトの名無しさん2006/11/02(木) 00:29:55
print map { $_->[0] } @$ref
0056532006/11/02(木) 00:34:37
ありがと
ただ
@$\のくみあわせで
print @{$・・@$ref->[0]};
といったぐあいに(@{@$ref->[0]}  みたいなかんじ)
で表現できたはずなんだ
どうしてもできない
おしえてほしい
0057デフォルトの名無しさん2006/11/02(木) 02:20:21
>>51
他人事ながら親切回答に感激
0058デフォルトの名無しさん2006/11/02(木) 08:29:24
>>56
perldoc perllol しても情報はないなぁ
> @part = @{ $AoA[4] } [ 7..12 ];
は単なる slice だし。

そういう方法があれば知りたいもんだ。
0059212006/11/02(木) 08:49:43
#!/Perl\bin\perl
$CSfile="CSfile.csv";
$TXfile="TXfile.txt";
$outfile="outfile.txt";
open (INTEXT, $TXfile) or die "$!";
open (INCSV, $CSfile) or die "$!";
open (OUT, "> outfile.txt") or die "$!";
@lines = <INTEXT>;
$line_amount = @lines + 1; #行数計算
while (<INCSV>) {
chomp ($_);# 改行コードの除去
@data = split(/,/, $_);# 各行をカンマ区切りで分割
for($i=0;$i<$line_amount;$i++){
$lines[$i] =~ s/$data[0]/$data[1]/g;
}
}
print OUT @lines;
close(INTEXT);
close (INCSV);
close (OUT);

なんとなくできましたが、
速度が遅すぎる点と、結果が文字化けしている点がいかんともしがたい。
CSfile.csv=4万行以上・TXfile.txt=2万行程度(検索・置換は全て日本語です)
改善策をご指導ください。
0060デフォルトの名無しさん2006/11/02(木) 09:16:50
>>59
置換対象のファイルを@linesに行ごとに入れてループでまわすよりは
全体を一つの変数$linesにいれてまとめて置換した方がたぶん速い。

$lines = do { local $/; <INTEXT> };

文字化けの原因はここに書いてある情報だけではないともいえないが
たぶんEUCかSJISそのままでやってるせいじゃないかと思うので内部は
unicodeにしたほうがいいだろう。全部一緒ならopenプラグマで

use open ':encoding(sjis)';

のようにすればまとめて指定できるはず。
0061デフォルトの名無しさん2006/11/02(木) 10:48:08
>>51
どうもありがとう!やってみます!
0062212006/11/02(木) 12:22:58
>>60
文字化けは、解消されました。

速度については、速くはなったと思いますが、それでも遅い感じがします。
perlの限界なのかな・・・・

いろいろありがとうございました!
0063212006/11/02(木) 12:59:25
追記:
次はC言語でやってみたいと思います。
C言語も全くしたことないけど・・・・
速いのかな・・・・
0064デフォルトの名無しさん2006/11/02(木) 13:22:15
>>59
問題なのは行数よりサイズだと思うんだが・・・。
ってかそんな遅くなるとかどんなファイル扱ってんだよ('A`)
0065デフォルトの名無しさん2006/11/02(木) 13:37:55
>>62
2万行の文字列を4万回置換だからそれなりに時間はかかるだろうな。

4万回s///するのと置換対象の文字列を全部 | でならべて
s/(文字列1|文字列2|...)/$h{$1}/g のようにするのとはどちらが
速いだろうか

あるいは発想を変えて、対応表を適当な有限状態オートマトンに
変換しといて置換対象の文字列を頭から食わすみたいな
アルゴリズムにするのもおもしろいかもしれない。

たとえば ab → d, ac → e

状態0:
aなら状態1へ
bなら状態2へ
それ以外はその文字を出力して状態0へ

状態1:
bならdを出力して状態0へ
cならeを出力して状態0へ
それ以外はaとその文字を出力して状態0へ

みたいな。
0066212006/11/02(木) 14:07:01

(´ヘ`;)
0067デフォルトの名無しさん2006/11/02(木) 14:29:13
Cならオブジェクト性能をマクロからミクロまで
自分でコントロールできるから試してみる
価値はあるな>63
OSコールが気に入らなきゃ、その部分を自分で
組み立てたっていいし
0068デフォルトの名無しさん2006/11/02(木) 14:29:24
辞書は予めソートしておき、辞書の1文字目がもしtxtに出現しなければ
同じ出だし辞書は全部飛ばし、別の出だし単語へ。
0069682006/11/02(木) 14:32:44
ソートしなくても、連想配列に1文字目該当無しフラグ作る等いろいろ。 $FG{'あ'}=1;
0070デフォルトの名無しさん2006/11/02(木) 15:08:23
> 4万回s///するのと置換対象の文字列を全部 | でならべて
> s/(文字列1|文字列2|...)/$h{$1}/g のようにするのとはどちらが
> 速いだろうか

/(文字列1|文字列2|...)/ より /文字列1/ or /文字列2/ or ... って分けた方が早いらしいよ。
・・・って、どれかひとつにマッチしたら他にマッチしない前提なのかな
0071212006/11/02(木) 15:21:50
C言語・・・こりゃ道程が遠いね

0072デフォルトの名無しさん2006/11/02(木) 19:45:27
$max_buf = $size - $now_size if $size - $now_size < $max_buf;

これで $now_size が $size より小さければ $max_buf は0になります。
$now_size が $size より大きければ $max_buf には $size より足りない数になります。

どうなるかは解ったのですが、そうしてこうなるのかが解りません。
どういう風に解釈したら良いのでしょう。

<例>
$size = 12
$now_size = 10
$max_buf = 0

<例>
$size = 10
$now_size = 12
$max_buf = -2
0073デフォルトの名無しさん2006/11/02(木) 20:06:12
>>72
> $max_buf = $size - $now_size if $size - $now_size < $max_buf;
>
> これで $now_size が $size より小さければ $max_buf は0になります。

ちがう。if文が偽を返しただけだ。



0074デフォルトの名無しさん2006/11/02(木) 20:14:27
>>73
ううん。
すみません、良くわかんないです。
ただ、理解する手がかりになりましたので勉強します。
回答をありがとうございました。
0075デフォルトの名無しさん2006/11/03(金) 20:42:55
>>59
毎回正規表現をコンパイルしにいってるから遅いとかはないかな?

このサンプルを元に作ってみたら?
日本語がほしけりゃPerl Cookbookを買いましょう。
ttp://www.unix.org.ua/orelly/perl/cookbook/ch01_18.htm
0076デフォルトの名無しさん2006/11/04(土) 13:25:02
>>74
> $max_buf = $size - $now_size if $size - $now_size < $max_buf;
これは
if( $size - $now_size < $max_buf ){
    $max_buf = $size - $now_size;
}
と同じです。っていうのは分かってるのかな・・・?
0077デフォルトの名無しさん2006/11/05(日) 00:10:10
chompみたいに、引数を省略すると$_を処理するサブルーチンってどう書くの?
0078デフォルトの名無しさん2006/11/05(日) 00:22:57
>>77
@_の要素数を見ればいくつパラメタが与えられたかわかるので
適当に分岐なりなんなりすればよい。
0079デフォルトの名無しさん2006/11/05(日) 04:24:45
長い文章から正規表現で$1 .. $7まで取り出して使っているのですが、条件式が長くなってしまいます。
途中で改行したいのですが、実際に条件式の途中で改行するとエラーになってしまいます。
解決策を教えてください。

条件式
$hoge =~ /VALUE="(.*?)"(?:.|[^.])*?VALUE="(.*?)".*?VALUE="(.*?)".*?VALUE="(.*?)".*?VALUE="(.*?)".*?VALUE="(.*?)"(?:.|[^.])*>(\d+)(?:\(hugahuga\)|\(hogehoge\))/;
0080デフォルトの名無しさん2006/11/05(日) 05:02:16
>>79
"x" をつける
0081デフォルトの名無しさん2006/11/05(日) 05:15:00
>>80
できました。
これ便利ですね。

どうもありがとうございました。
0082デフォルトの名無しさん2006/11/05(日) 13:16:32
$hoge = "熊のプーさん";
$hoge =~ /プーさん/;

を実行すると

Unmatched [ in regex; marked by <-- HERE in m/プー <-- HERE さん/ at C:\hoge\test.pl

とエラーになります。
パターンの先頭がパー、ピー、プー、ペー、ポーにだとエラーになるようです。

$hoge =~ /\プ\ー/;

エスケープしてもうまくいきません。
どうしてでしょうか?
0083デフォルトの名無しさん2006/11/05(日) 13:29:26
>>82
長音(ー)の2バイト目が 0x5B で、'[' (0x5B) として解釈されてしまうからです。
\Q と \E で囲むと、その間の文字列は正規表現として解釈されなくなります。

/\Qプーさん\E/

ではどうでしょうか?
0084デフォルトの名無しさん2006/11/05(日) 13:31:59
>>82
全部EUCで書いちゃうのも手かもね。
0085デフォルトの名無しさん2006/11/05(日) 17:56:01
SnUploaderについての質問です。
ファイルをアップすると[upxxxx.xxx]という名前に強制的になりますが、
これを[MAQxxxxx.MP4]という様にしたいです。
(xxxxxの部分は、アップされた順に00001,00002,00003という感じに)
どうすれば良いのでしょうか?
また、MP4ファイルをアップしそれを落とそうとしてファイル名のところを
クリックすると、QuickTimeによって再生され、保存することが出来ません。
これを再生されること無く、ファイル名をクリックしただけでDLが始まるようにするのは
どうすれば良いのでしょうか?
分かりにくい文章かもしれませんが、教えてください。お願いします。
0086デフォルトの名無しさん2006/11/05(日) 18:59:54
>>85
前半はすれ違い
後半はいた違い
0087デフォルトの名無しさん2006/11/05(日) 19:12:36
>>86
え・・・
uploder.cgiの中身を書き換えるんじゃないんですか?
そうだと思ってPerlのスレにに書いたのですが・・・。
もしかして、ここじゃなくてCGIの質問スレに書くべきでしたでしょうか。
0088デフォルトの名無しさん2006/11/05(日) 19:55:09
>>87
>>1
0089デフォルトの名無しさん2006/11/06(月) 00:06:18
>>87 書き込みするまえに2chの使い方,板とスレのそれぞれのローカルを覚えろ。それまではROMってろ
0090デフォルトの名無しさん2006/11/06(月) 00:55:10
そうまで言わなくてもいいだろ
0091デフォルトの名無しさん2006/11/06(月) 01:49:21
「親切10回につき罵倒1回」を心がけましょう
0092822006/11/06(月) 02:11:23
>>83-84
\Q, \Eを使って解決しました。
レスありがとうございました。
0093デフォルトの名無しさん2006/11/06(月) 04:18:12
printで標準出力に送られた文字列ををログとしてテキストファイルにも保存したいですのですが、
今は下のようにめんどくさいことをしています。何かうまい方法はありませんか?

print "ほげ";
print LOG "ほげ";

print "ふがふが";
print LOG "ふがふが";
0094デフォルトの名無しさん2006/11/06(月) 04:33:50
>>93
perl のプログラムでは標準出力に出すだけ。

tee を使ってリダイレクトするか、
単にリダイレクトしてそのファイルを別端末で tail -f する。
0095デフォルトの名無しさん2006/11/06(月) 04:54:25
>>93
二穴用のさぶる〜ちん作りゃいいやん
0096デフォルトの名無しさん2006/11/06(月) 05:29:48
>>93
open(STDOUT,"|tee log");
0097デフォルトの名無しさん2006/11/06(月) 06:20:27
前スレで出ていたIO::Teeとか。
0098デフォルトの名無しさん2006/11/07(火) 04:16:20
質問させてください。

  $data { 'Class_A' } [ 0 ] { 'FirstName' } = '太郎' ;

みたいな配列とハッシュを組み合わせた変数を用意しようと思います。
リファレンスとか多次元とかサブルーチンとかごちゃごちゃで混乱してます。


【1】変数の値を生成し、代入したい

  my %data;
    #(略。ループとかDBからの取得とか)
  my %hash;
  $hash{'FirstName'} = '太郎';
  $hash{'FamilyName'} = '田中';
  push ( @data{'Class_A'} , \%hash );
    #(略。ループ終了とか)

と書いてみたのですが、型が違ぇよボケ(意訳)と言われてしまいました。
(実際には、Class_Aや田中、太郎の部分にはデータベースから取得した値が入る)

仕方ないので、

  my @tmp = @data{'Class_A'};

と、あらかじめコピーしておいてから、最後に

  push(@tmp,\%hash);
  @data{'Class_A'} = \@tmp;

一時ファイルの中身を戻すとかやってる始末です。
もうちょっとスマートな方法はありませんでしょうか。
0099デフォルトの名無しさん2006/11/07(火) 04:17:50
なお、データベースから読み込んだとき、クラスごとや出席番号順に来るとは限りません。
A組→B組→B組→B組→C組→A組→C組 とかもありえます。
各クラスの生徒数は不明です。


【2】特定のクラスに所属する生徒の情報を取り出したい。
なお、取り出す順番(出席番号)については言及しない。もちろんしてもいい。

  foreach my $key (keys @data{'Class_A'} )

というループを作ってみたのですが、最終的な値(田中とか太郎とか)を取得する方法が分かりません。

  $data{'Class_A'}[$key]{'FirstName'}
  $key{'FirstName'}

など幾つか試してみましたが、全く取得できる気配はありませんでした。
(どちらも「太郎」などの文字列の取得を期待しています)
0100デフォルトの名無しさん2006/11/07(火) 04:36:35
>>98
push ( @data{'Class_A'} , ¥%hash );
のところを
push ( @{$data{'Class_A'} }, ¥%hash );
でいいんじゃないか
0101デフォルトの名無しさん2006/11/07(火) 04:44:23
>>99
my %data;
#(略。ループとかDBからの取得とか)
my %hash;
$hash{'FirstName'} = '太郎';
$hash{'FamilyName'} = '田中';
push (@{$data{'Class_A'}},¥%hash);

foreach my $class ('Class_A', 'Class_B', 'Class_C') {
 foreach my $student (@{$data{$class}}) {
  print $student->{'FirstName'} . $student->{'FamilyName'} . "¥n";
 }
}
0102982006/11/07(火) 04:48:00
こんな遅くにも関わらずありがとうございます。
これ以上パソコンとお見合いしてると明日(というか今日)の仕事に響くので
検証は夜にでもやりたいと思います。

ほんとうにありがとうございました…… zzz
0103デフォルトの名無しさん2006/11/07(火) 07:15:07
既に解決しているようだが質問するときはエラーメッセージは勝手に意訳せずに
そのまま貼るのが基本。
0104デフォルトの名無しさん2006/11/07(火) 17:23:16
もうちと解説してみる。
hashやlistの値として、直接 hash や list は格納できないが、リファレンスは格納可能。
従って、
$data{'Class_A'}->[0]->{'FirstName'} = '太郎';
ならOK。しかしややこしいことに、上記は
$data{'Class_A'}[0]{'FirstName'} = '太郎';
と書いても同様に解釈される。これだと表記上、hash の値にlistが
格納されているように見えるが、実際には list のリファレンスが格納されている。

list のリファレンスなので、その全体は @{$data{'Class_A'}} で参照する。
@$data{'Class_A'} じゃダメ。
0105982006/11/07(火) 20:02:45
ありがとうございます、無事に解決しそうです。
勘でコーディングするだけでなく、しっかりと何をしているか認識しないと駄目ですね。
Cのポインタはなんかはすぐに理解できたんですが、Perlはそれ以上に混乱しそうです。

>103
おっしゃる通りです。以後気をつけます。

0106デフォルトの名無しさん2006/11/07(火) 20:13:57
↓のように、配列に変数を代入できますか?

@array=($sec,$min,$hour,$day,$mon,$year);
0107デフォルトの名無しさん2006/11/07(火) 20:38:34
>>106
質問するより
print join(',', @array) . "¥n";
で試した方がはやくね? 釣り?
0108 ◆TWARamEjuA NGNG?BRZ(6667)
やってみたのか?
0109デフォルトの名無しさん2006/11/07(火) 20:54:03
>>107
釣り?
0110デフォルトの名無しさん2006/11/07(火) 21:11:17
>>107,108
実行できる環境じゃないんです;;
01111062006/11/07(火) 21:11:55
すいません
>>106=110です
0112デフォルトの名無しさん2006/11/07(火) 21:13:37
print "aa";を実行するとaaと画面に表示されますか?
実行できる環境じゃないんです;;
0113デフォルトの名無しさん2006/11/07(火) 21:17:48
20年くらい前は紙の上だけでプログラム書くのがプログラマだったんだっけ。
01141062006/11/07(火) 21:23:36
もういいです
C++でもJavaでもできるので、できるものとして書いていきます
0115デフォルトの名無しさん2006/11/07(火) 21:36:29
いってらっしゃい
0116デフォルトの名無しさん2006/11/07(火) 21:41:21
>>106
できない。
0117デフォルトの名無しさん2006/11/07(火) 21:49:59
実行できる環境じゃないのに何のために書いてんだw
0118 ◆TWARamEjuA NGNG?BRZ(6667)
(´-`).。oO(そんなことを宣っているやつがC++だろうがJavaだろうが、はたまたObjective-C++2.0でもまともなことは出来ない伊予柑♪)
0119932006/11/07(火) 23:19:58
$tee = new IO::Tee(\*STDOUT, ">>log.txt");
print $tee "ほげふが";
で解決しました。
レスありがとうございました。
0120デフォルトの名無しさん2006/11/07(火) 23:55:34
<FORM ACTION="hoge.cgi" method="POST">
<INPUT TYPE=HIDDEN NAME=huga VALUE="huge">
<INPUT TYPE=SUBMIT NAME=ok VALUE="送信">
<INPUT TYPE=SUBMIT VALUE="取り消し">
</FORM>

これを送信したいんですが下のようにすると取り消しが送られてしまいます。
どうすればいいですか?

$string = "上のHTML";
$url = 'http://hoge/hoge.cgi';
$string =~ /NAME=huga\sVALUE="(.*?)"/;
%formdata = ('huga' => $1);
$ua = LWP::UserAgent->new;
$req = POST($url, [%formdata]);
$res = $ua->request($req);
0121デフォルトの名無しさん2006/11/08(水) 00:11:16
>>120
>>1
0122デフォルトの名無しさん2006/11/08(水) 00:17:34
$string = <<EOF;
<FORM ACTION="hoge.cgi" method="POST">
<INPUT TYPE=HIDDEN NAME=huga VALUE="huge">
<INPUT TYPE=SUBMIT NAME=ok VALUE="送信">
<INPUT TYPE=SUBMIT VALUE="取り消し">
</FORM>
EOF
$string =~ /NAME=huga¥sVALUE="(.*?)"/;
%formdata = ('huga' => $1);
print join(',', %formdata) . "¥n";

>>120は上記を参考にして出直してください。
上記の結果が予想と一致するのであれば、スレ違いかな。
予想と違うのであれば、どっかがおかしい。
0123デフォルトの名無しさん2006/11/08(水) 00:36:44
ふと思ったんだけど、
HTMLを標準出力やファイルに出力するスクリプト自体はWebProg板じゃなくてもOKよね?
01241202006/11/08(水) 00:39:04
すみません説明不足だったのかもしれません。
簡易HTTPブラウザを作っていて、
以下のHTMLを受け取った時に解析して送信するといった処理をしたいのです。
やはりスレ違いでしょうか?

<FORM ACTION="hoge.cgi" method="POST">
<INPUT TYPE=HIDDEN NAME=huga VALUE="huge">
<INPUT TYPE=SUBMIT NAME=ok VALUE="送信">
<INPUT TYPE=SUBMIT VALUE="取り消し">
</FORM>

use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
$string = "上のHTML";
$url = 'http://hoge/hoge.cgi';
$string =~ /NAME=huga\sVALUE="(.*?)"/;
%formdata = ('huga' => $1);
$ua = LWP::UserAgent->new;
$req = POST($url, [%formdata]);
res = $ua->request($req);
0125デフォルトの名無しさん2006/11/08(水) 01:03:51
>>124
CGI/HTTPの問題であればスレ違い。
文字列のパーシングとかならOK。
で、文字列のパーシングに関しては良さそうに思う。
>>122 のコードで確認しる。
>>124は、どこ(CGI/HTTP/文字列処理/etc.)が怪しいのか切り分けできてるのか?
01261202006/11/08(水) 01:25:48
>>125
ありがとうございます。>>122の意味を掴めていませんでした。
送信、取り消しの違い(ok)をどうやって区別するかを尋ねましたが、スレ違いでした。
0127デフォルトの名無しさん2006/11/08(水) 01:40:06
>>126
submitが複数あるフォームでどのsubmitが押されたかを知りたいってこと?
もしそうなら完全に板違いだね。
webprog板の初心者perlスレが良いと思う。
0128デフォルトの名無しさん2006/11/08(水) 01:41:38
>>127
とっくにそのスレに移動してんだろ。
死ねよ俺www

ごめんなさい…orz
0129デフォルトの名無しさん2006/11/08(水) 08:29:46
>>128
罰として次回のスレ立てを命ずるw
0130デフォルトの名無しさん2006/11/08(水) 15:24:02
質問です

ARR_1[1] =1;
@ARR_2 = @ARR_1;
++$ARR_2[1];
print ($ARR_1[1]);
だと当然 1が出力されます

ARR_1[1][1] =1;
@ARR_2 = @ARR_1;
++$ARR_2[1][1];
print ($ARR_1[1][1]);
だと何故か1ではなく、$ARR_2[1][1]の値である2が表示されてしまいます
どこか間違っていますでしょうか?
0131デフォルトの名無しさん2006/11/08(水) 15:38:38
$ARR_1[1]と$ARR_2[1]には何が入ってるか調べる
01321302006/11/08(水) 15:52:23
>>>131様
よく分かっておりませんが

上の場合は 両方とも、1というスカラー値が入っております

下の場合は、両方とも配列へのリファレンスが入っています
(なぜか$ARR_1と$ARR_2には同じ物へのリファレンスが入ってしまってます)
0133デフォルトの名無しさん2006/11/08(水) 15:52:54
すみません
Net::FTPのquotコマンドの引数の書き方がわからないのですが
quot (CMD [,ARGS]) この場合
$ftp->quot("/usr/bin/du", "-k -s ../")
これであってますか?


0134デフォルトの名無しさん2006/11/08(水) 15:57:43
>>132
リファレンスをコピーしてもそれらが指す実体は変わらない。
ディープコピーしたければ以下のモジュールを。
http://search.cpan.org/~rdf/Clone-0.22/ (要コンパイル)
http://search.cpan.org/~evo/Clone-PP-1.02/ (PurePerl)
0135デフォルトの名無しさん2006/11/08(水) 16:08:31
>>132
>(なぜか$ARR_1と$ARR_2には同じ物へのリファレンスが入ってしまってます)
リファレンスが入った配列を代入したんだから、そうなっていて正常
>++$ARR_2[1][1];
ここでは実体を変えてる

昔の友達の電話番号にかけたら違う人が出た、みたいな
01361302006/11/08(水) 16:22:12
親切な説明、ありがとうござました
私の認識が間違っておりました

ここに書いたのは省略したコードで
実際に詰まってしまった実コードはもっと複雑なスパゲティになっております
全部見直さなきゃ。
0137デフォルトの名無しさん2006/11/09(木) 00:01:25
WEB検索でよく使われる構文
(A B) (C D)
をSQL文
(x='%A%' or x='%B%') and (x='%C%' or x='%D%')
に変換するスクリプトを簡単に書く方法はないでしょうか?

Text::Balancedを使って()の対応はチェックしていますので、
()の対応は取れているという前提でやっているのですが
なかなか上手くいきません。
0138デフォルトの名無しさん2006/11/09(木) 10:32:50
ファイルハンドルの渡し方で質問なんですが
このようにするしかないのでしょうか?
test(*OUT);
sub test {
local *FD = shift;
flock(FD, 2);
}
0139デフォルトの名無しさん2006/11/09(木) 10:55:14
昨日ファイルから読み込んだデータ('機能@')&キー('@')で
index ($data,$key,2)を実行したら3が返ってきたので、
"能"の第二バイト\が原因と考えそれを他の文字に置き換えたら
正しく 4 が返ってきました。

で、今日こんな場合の上手い対処方法はないか質問しようと
もう一度、index ($data,$key,2)を何も手を加えずに実行したら
4が返ってきました。

indexの動作に何か環境条件が影響するんでしょうか?
01401392006/11/09(木) 10:57:50
あ、一個書き忘れ。'機'の第二バイトは @ です
0141デフォルトの名無しさん2006/11/09(木) 12:25:32
>>138
渡す方は、
open(FD, "hoge") or die;
test(*FD{IO});

または

my $fh;
open($fh, "hoge") or die;
test($fh);

受け取る方はどちらでも
sub test {
my $fh = shift;
}

ただし、perl 5.8 以降だった気がする
01421382006/11/09(木) 13:46:55
>>141
ありがとうこざいます。
ということは>>138のは間違ってますか?動作はしますが
0143デフォルトの名無しさん2006/11/09(木) 15:09:36
>>142
間違っているわけではないけど、use strict できないし、古めかしい。
perl 5.6 以前のバージョンでは(記憶に間違いがなければ)、>>138のような
書き方をせざるを得なかったんじゃないかな。
01441382006/11/09(木) 15:43:13
なるほどどうもです。ありがとうこざいました。
0145デフォルトの名無しさん2006/11/09(木) 15:46:20
$ascii = '[\x00-\x7F]';
$twoBytes = '[\x81-\xFC][\x40-\xFC]';
$string =~ /^(?:$ascii|$twoBytes)*?(?:\Q$key\E)/;

これでマッチした位置をしる方法ないですか?

length $` は、0が返ってきました。

perl v5.6.1
0146デフォルトの名無しさん2006/11/09(木) 15:56:30
パターンが^ではじまってるんだからマッチしたとすれば文字列先頭からなんじゃないの?
($*をいじってない限り)
01471452006/11/09(木) 16:17:31
事故解決しますた

length ($string) - length ($key) - length ($')
0148デフォルトの名無しさん2006/11/09(木) 16:56:34
素直な方法は

$string =~ /^(?:$ascii|$twoBytes)*?(?:\Q$key\E)/;

を

$string =~ /^(?:$ascii|$twoBytes)*?(\Q$key\E)/;

にかえて $-[1] じゃないか。$keyの部分がキャプチャされる
のがどうしても嫌なら


$string =~ /^(?:$ascii|$twoBytes)*?()(?:\Q$key\E)/;

でもいいがちと見難いかも。

$'はパターンマッチ使う場所がそこだけしかないような小さい
プログラムならいいが、一般的にはあまりお勧めしない。
0149デフォルトの名無しさん2006/11/09(木) 17:16:56
>>145
解決隅にレスるのもなんだが pos 使えば?
my $str = 'hogefugehagehoge' ;
print +( pos $str ) . "\n" while $str =~ /(hage)/g ;
01501452006/11/09(木) 17:59:53
>>148
あっ、そっちの方が全然スマートですね。頂きます。

ところで、$' が芳しくない理由はどんなことに起因しますか?
参考サイトがあったら教えて下さい。勉強します
0151デフォルトの名無しさん2006/11/09(木) 18:49:47
>>150
> ところで、$' が芳しくない理由はどんなことに起因しますか?

添付マニュアルに書いてある。
■ このスレッドは過去ログ倉庫に格納されています