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

【Perl】初心者コーナーPart10

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。02/02/24 22:18ID:zOj6Yq/3
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

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

1と3が無いと誰も答えられないよ、良い回答は良い質問から。
一緒に勉強しましょう。

参考書籍はこちら【【Perl,CGI】参考書籍 第2版 】
http://pc.2ch.net/test/read.cgi/php/988809842/
CGIの質問はこちら【CGIだけど、なんか質問ある?part5】
http://pc.2ch.net/test/read.cgi/php/1009331505/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般】
http://pc.2ch.net/test/read.cgi/php/991313362/

過去ログ、その他の役立ち情報は>>2-10を見よう。
0172nobodyさん02/03/03 21:08ID:???
つか -cw は文法チェックするだけ。普通はデバッグモードとは言わん。
例えば、以下のコードはSynax OKだが実行した瞬間死ぬ。

#!/usr/bin/perl
foo()
__END__
0173nobodyさん02/03/03 21:14ID:/fm96Lfb
ActivePerlをインストールしたら、ダウンロードしてあったCGIスクリプト
のplファイルが黄色いボールのアイコンになってしまいました。
この関連付けを解除する方法は無いですか?このままでも問題無し?

あと、いずれはCGIスクリプト書けるようになりたいですが、まず最初の
段階ではActivePerlをインスコして参考書読みながらコマンド打っていくの
がいいんでしょうか?サーバソフトとかまだ入れてないんですが・・
0174nobodyさん02/03/03 21:15ID:???
>>173
>インスコして

一生無理だ。あきらめろ。
017516602/03/03 21:16ID:zlwT/08t
>170
Apacheのログを見たら分かりました。
print "Content-type: text/html\n\n"を忘れてBad headerでした。
超初心者的ミス、鬱だ。
017617302/03/03 21:24ID:/fm96Lfb
>>174
そんな事言わずにお願いします。
>インストールして
訂正します。すみませんでした。

ちなみに参考書は「すぐわかるPerl 深沢千尋/著」を買ってきました。
0177nobodyさん02/03/03 21:26ID:???
>>176
その本は素晴らしいよ。

基本的にはコマンドプロンプトでPerl a.cgiとするのが王道。
俺は秀丸マクロで開発環境作ったけど。
0178nobodyさん02/03/03 21:26ID:???
>>176
じゃあまずその本を読破しろ。
017916302/03/03 23:17ID:K6uur/rZ
>>171
CSVデータの中に空欄があったら処理を実行せずにデータがあればそれから処理を実行したいんです。
0180163=17902/03/03 23:22ID:K6uur/rZ
具体的には
open(DATAFILE,"data.csv");
while (<DATAFILE>) {
push my @TMPDATA ,(split /,/)[0,5] ;
if (@TMPDATA[0] < @TMPDATA[1])
{
push @TIME ,(split /,/)[1];
}
}
のifのところで@TMPDATA[0] 、@TMPDATA[1]のどちらかが空欄なら以下の処理をせずに終わりたいんです。
018117102/03/03 23:32ID:???
>>180
なるへそ。そしたら、if の条件に「どちらも空じゃなければ」を追加すれば
いんじゃないかな。
0182nobodyさん02/03/03 23:42ID:???
つーか誰か配列スライス使ってることとかつっこんでやれよ…
0183nobodyさん02/03/04 00:10ID:???
グローバル変数なのにmyを使っている人は何を考えているのでしょうか。
strict下ならvarsモジュールを使えばいいのに。

localとは違うからいいの?
01849502/03/04 00:12ID:KNDHr4No
またtie について質問させてください。

sub sub_routin {
my (%data) = @_;

use strict;
use Fcntl;
use SDBM_File;

my %hash = ();
my $data_base = 'data_base';

tie (%hash, 'SDBM_File', $data_base, O_CREAT|O_RDWR, 0666);

#この命令自体はあまり意味は無いが、要はハッシュのハッシュを使いたい

foreach my $number (1..100) {
while ( my ($key, $value) = each (%data) ) {
$hash{$number}->{$key} = $value;
}
}
untie (%hash);
}

上のように、tieからuntieの中でハッシュのハッシュを使おうとすると
Can't use string ("HASH(0x1c37ddc)") as a HASH ref while "strict refs"(以下略)
などと怒られてしまい、使えません。多次元構造のデータの外部化って無理なんですか?
018518302/03/04 00:12ID:???
例えばこんなの
http://www.midnightroam.org/source/minibbs2_77.txt
0186nobodyさん02/03/04 00:16ID:???
無理です。
$hash{$number, $key} = $value にすれば?
0187nobodyさん02/03/04 00:17ID:???
>>183
漏れの場合はvarsを知らなかったので、myを
使ってる。「strict使ったら怒られたから、
myを付けたらOKだった」という感じだった。

varsを使った方がいいのかな。
0188nobodyさん02/03/04 00:18ID:???
>>187
グローバル変数なら素直にvars使った方が良いだろ。A
018914902/03/04 02:25ID:zvOvcxtF
>>150 遅くなりましたがレスありがとうございました

自分なりにいろいろやってみたのですが、全く別の問題だと分かりました

$string = 'Watashi ga Kaita. Watashi ga Keshita';
while ($string =~ /Watashi/igo) {
 $value = 'Watashi(=Yamada)';
 $string =~ s/Watashi/$value/i;
}
print "$string";

なのですが、無限にループ(?)しているような状態になります
表示したい文字列は
Watash(=Yamada)i ga Kaita. Watashi(=Yamada) ga Keshita
にしたいのです
この例の場合には置換で1行で出来るのですが、whileループの中で
いろいろと処理をさせたいのでこの様にしています

$value = 'Ore(=Yamada)';
$value = 'Yamada';

のようにすると無限ループのような状態にならずに

Ore(=Yamada) ga Kaita. Ore(=Yamada) ga Keshita
Yamada ga Kaita. Yamada ga Keshita

と変換されて表示されるのでパターンマッチに使った文字列から
始めない場合はうまくいくようなのですがその理由も良くわかりません

なんかそもそもアプローチ自体がおかしいような気がしてきてはいるのですが
ご教授いただけるとうれしいです
0190nobodyさん02/03/04 02:27ID:???
すいません

>表示したい文字列は
>Watash(=Yamada)i ga Kaita. Watashi(=Yamada) ga Keshita
Watashi(=Yamada) ga Kaita. Watashi(=Yamada) ga Keshita
です 申し訳ありません
0191nobodyさん02/03/04 03:03ID:???
すいません、ニュースっぽい系のcgi作ろうとしてるんですが
鯖に存在するファイルの読み書きは知ってるんですが
ファイル自体を出力する処理方法ってありますか?
(更新ごとに新しいファイルを出力するみたいな)
よろしくお願いします。


0192nobodyさん02/03/04 03:25ID:???
>>191
ファイル名変えればいいんじゃ?
ユーザーにファイル名を入力させるのはやめといたほうがいい。
0193nobodyさん02/03/04 05:22ID:???
>>191
open(FILE,">new.dat");
0194nobodyさん02/03/04 10:10ID:???
>>191
ファイルを作成するディレクトリのパーミッションを666に。
019519402/03/04 10:11ID:???
>>194
寝ぼけてた・・・777です。
0196nobodyさん02/03/04 10:14ID:???
>>189
Watashi ga Kita Watashi ga Kita
↓
Watashi(=Yamada) ga Kita Watashi(=Yamada) ga Kita
↓
Watashi(=Yamada)(=Yamada) ga Kita Watashi(=Yamada)(=Yamada) ga Kita
↓
Watashi(=Yamada)(=Yamada)(=Yamada) ga Kita Watashi(=Yamada)(=Yamada)(=Yamada) ga Kita


$string =~ /Watashi$s/igo


0197nobodyさん02/03/04 10:29ID:???
>>184
MLDBMを使えばそれ*らしき*操作は出来る。
ただし万能じゃないんで詳しい事はドキュメント読んでくれ。
0198nobodyさん02/03/04 10:32ID:???
>>196
訂正。

$string =~ /Watashi\s/igo
0199nobodyさん02/03/04 13:40ID:???
PerlでCプリプロセサの#defineと同等の機能はありますか?
0200nobodyさん02/03/04 13:43ID:???
perlrun の `Switches' より

-P causes your script to be run through the C
preprocessor before compilation by Perl. (Because
both comments and cpp directives begin with the #
character, you should avoid starting comments with
any words recognized by the C preprocessor such as
"if", "else", or "define".)
0201nobodyさん02/03/04 13:45ID:???
>>200
あの、、、#defineじゃなくて#defineと同等の機能があるかどうか聞いているんですけど・・・・
0202nobodyさん02/03/04 13:52ID:???
ないんですね。素直に変数を使います。
0203nobodyさん02/03/04 13:56ID:???
constant pragma は#defineに似ている

use constant NDEBUG => 1;
use constant STRING => "hello, world!\n";

if(defined &NDEBUG){
print STRING;
else{
# ..
}

それはそうと>>201は何故こんなに偉そうなんだ?
0204nobodyさん02/03/05 02:17ID:???
>>192-194さん、どうもありがとうございます
0205nobodyさん02/03/05 06:00ID:???
>>189
whileループの突入条件とそのループ内で同じ文字列のマッチングを行っているのが原因。
これでは文字列のどこまでマッチ作業を試行したのかわからなくなってしまうよ。
具体的にはwhileループ内のマッチ作業によってpos($string)がundefで上書きされてしまう。

$string = 'Watashi ga Kaita. Watashi ga Keshita';
while ($string =~ /Watashi/ig) { # ←◆g修飾詞によってpos($string)が設定される。
  $value = 'Watashi(=Yamada)';
  $string =~ s/Watashi/$value/io; # ←◆pos($string)がundefで上書きされる。(゚д゚)マズー
}
print "$string";

要するに$stringのマッチ開始位置が巻き戻ってしまう。
このため突入条件のマッチングはg修飾詞があっても常に$stringの先頭から行われてしまい、
$string内にWatashiという文字列がある限りwhileがループを続けてしまう。

>189がやりたい(であろうと漏れが考えた)事をむりやり書き下してみると、

# pos再設定とマッチ以後の文字列置換でむりやり解決
$string = 'Watashi ga Kaita. Watashi ga Keshita';
while ($string =~ /Watashi/ig) {
  $value = 'Watashi(=Yamada)';
  my $position = pos $string;
  if (substr($string, $-[0]) =~ s/Watashi/$value/io) {
    $position += length $value;
  }
  pos $string = $position;
}
print "$string\n";

こんな感じになるんだろうか。でもこんなスクリプトは見た事が無い。
アプローチというか何というか、たぶん他にもっと良い書き方があるのだと思う。
単純に解決したいならループ内で $string =~ s/Watashi(?!\(=Yamada\))/$value/io とか、
処理を挟むなら $string =~ s/Watashi/&process(...)/eg とか。
取り敢えず、普通whileの突入条件とそのループ内で同じ文字列のマッチングは行わない。
perlretutやperlop,perlfaq6などを読むと良いかもね。

つうか正直何をやりたいのか良くわからないから的外れかもしれない。そんときゃスマソ。
0206nobodyさん02/03/05 06:12ID:???
あ、むりやり解決のスクリプト間違っているわ。
$position += length($value) - length('Watashi');
だね。どーでもいいか。
0207nobodyさん02/03/05 13:00ID:???
&subname(); で飛ばす場合と、
&subname; で飛ばす場合は、どちらの方がメモリ消費が少ないのでしょうか?
自分は()を付けると、サブルーチン先の@_と、呼び出しもとの@_は別物と認識するので、
@_に代入するとその分メモリを消費するが、何も代入しない場合はどっちでも変わらないのでは?
と考えるのですが
020820802/03/05 22:03ID:OFFg29v+
パスワード認証のプログラムが作りたくて、下記のようなものを作ったのですが、
いつも「エラー2」が出てしまいます。何でうまくいかないのかさっぱり分かりません。
どなたかお知恵を貸してください。
acountlist.dat はこんな感じになってます。
id01:pwd01:point01
id02:pwd02:point02
...
------------------------------------------------------------
print "IDを入力してください\n";
$id = <STDIN>;
chop($id);
print "パスワードを入力してください\n";
$pwd = <STDIN>;
chop($pwd);

open(DATA,"<../xxxxxxx/acountlist.dat") or die;
while($line = <DATA>){
chop($line);
@acount = split(/:/,$line);
if($id eq $acount[0]){
if ($pwd eq $acount[1]){
print "いらっしゃいませ $acount[0] さん\n";
print "現在あなたは $acount[2] ポイントお持ちです\n";
exit;
}else{
print "エラー1";
exit;
}
}else{
print "エラー2\n";
exit;
}
}
close(DATA);
------------------------------------------------------------
0209nobodyさん02/03/05 22:23ID:???
>>208
acountlist.dat (accountlist.datのスペルミスだとは思うけど)
の最初の行に書いてある人はOKだね。
0210nobodyさん02/03/05 22:24ID:???
>208
それじゃid01の人しか受け付けないよ.
021120802/03/05 23:22ID:???
209さん、210さんご教授ありがとうございました。
おかげさまでうまくいきました。
0212nobodyさん02/03/05 23:55ID:???
スタイルシートを挿入している部分にnext 2 tokensってエラーがでます。
どうせましょう
0213nobodyさん02/03/06 10:16ID:???
ランダムな数のうち、10の倍数だけを取り出す方法ってありますか?
データベースから引っ張ってきた件数をGoogleみたいに
1 2 3 4 5 ・・ と自動的にリンクを貼りたいんですが。
0214nobodyさん02/03/06 10:23ID:???
>213
10〜100までの10の倍数の乱数を出したい場合。
1〜10の乱数を出して10倍する。
0215nobodyさん02/03/06 10:25ID:???
む?
ひょっとして、乱数は関係ない?

foreach(1 .. 100){
if($_%10==0){print qq(10の倍数);}
}
って事?
0216nobodyさん02/03/06 10:34ID:???
>>215
ヒントありがとう
実験してみます。
0217nobodyさん02/03/06 14:04ID:???
んー駄目だ
10の倍数とか関係なかった(ごめん)
どうやったらデータベースから引っ張ってきたデータ件数を
Googleみたいに 1 2 3 4 5 ・・ ってリンクできるんだろ
perlじゃないのかな・・・
0218nobodyさん02/03/06 14:13ID:???
>217
$i=0;
foreach(1 .. $n){
if($_%100==0){print qq(<a href=./hoge.cgi?start=$_>) . ++$i . qq(</a>);}
}

googleはこんな感じだろ。
0219nobodyさん02/03/06 14:16ID:???
いや、検索件数を数え終わってからという手もあるか。
$j = HIT数;
for($j=0;$j<=$n/100;$j++){
print qq(<a href=./hoge.cgi?start=) . ($j*100) . qq(>$j</a>);
}

ちなみに>218でもこの方法でも0 1 2 3 となるから、実際には1を足すように。
0220nobodyさん02/03/06 14:17ID:???
悪い。
>219の最後の一行は忘れて。
頭寝てるかもしれないからもう沈むわ。
混乱させてスマン。
0221nobodyさん02/03/06 14:20ID:???
>>217
Perlを疑う前に自分の頭を疑えよ。
0222nobodyさん02/03/06 14:29ID:???
>>220
ありがとう!

>>221
自分の頭は疑う余地もないので助けて貰いました(w
0223nobodyさん02/03/06 15:22ID:???
>>220
成功しました。
for文とは・・・
0224nobodyさん02/03/06 15:46ID:???
>>223
聞かなかった事にする。
0225nobodyさん02/03/06 16:04ID:???
(まさか)for文とは・・・(気が付かなかった・・・鬱)

の略ですm(_ _)m
0226nobodyさん02/03/06 21:21ID:qVNAtP8C
携帯用の参照制限はCGIで可能なのでしょうか?
教えて下さい。
0227nobodyさん02/03/06 21:29ID:???
半角カナの使用って何が問題なの?
正規表現に通したりすると落ちたりするんですか?

あと2バイト文字でファイル名を作らせるのはまずいですか?
URIエスケープすればどうだろう?
0228nobodyさん02/03/06 21:33ID:???
ttp://www.zukeran.org/shin/jdoc/hankaku-kana.html
この辺を参考に。
0229nobodyさん02/03/06 21:49ID:???
>>226
User-Agent 見て弾けばよかろう。
0230nobodyさん02/03/06 22:04ID:???
>228
ありがとう。
メールやネットニュースが対応してないので使わないクセを付けようということなのかな。

そういや,おれの通ってる大学のイタイ教師がメールのフッタに
「半角カナが世にはびころうとする風潮に断固反対する会 会員No.xx」とか書いてたのを思い出した。

どーでもイイが・・・
0231かなり初心者02/03/06 22:08ID:+Uo+pWis
$messageの文字列の中のどこかに、『>>3』のような文字が入っていて、
それを<a href="3"> >>3 </a>のように置換するやり方ってどうやるので、
しょうか?(ちなみに、数字は可変します。)

お願いします。(コードでご説明下さい。)
0232nobodyさん02/03/06 22:11ID:???
>231
$message =~ s/>>([0-9]*)/<A HREF="$1">$1</A>/g;
0233nobodyさん02/03/06 22:12ID:???
ちなみに$1には数字だけが入る。

$message =~ s/>>([0-9]*)/<A HREF="http://xxxx.xx.com/xxx.cgi?Res=$1">$1</A>/g;
などにすると良い。
0234nobodyさん02/03/06 22:14ID:???
$message =~ s/>>([0-9]+)/<A HREF="http://xxxx.xx.com/xxx.cgi?Res=$1">$1</A>/g;

だった。
0235nobodyさん02/03/06 22:16ID:???
>>231
s#>>(\d+)#<a href="$1">>>$1</a>#go;
0236nobodyさん02/03/06 22:17ID:???
$message =~ s!>>([0-9]+)!<A HREF="http://xxxx.xx.com/xxx.cgi?Res=$1">$1</A>!g;

じゃないとバグるな。
0237nobodyさん02/03/06 22:19ID:???
goのoって何?「変数展開を一回行う」ってどういう意味?
0238かなり初心者02/03/06 22:27ID:+Uo+pWis
レスありがとうございます。

数字なのですが、2桁の場合も考えられます。
その場合でも、ご提示頂いた物でOKなのでしょうか?

お願いします。
0239nobodyさん02/03/06 22:30ID:???
>238
ローカルで試してみろよ。
できるから。
024023502/03/06 22:33ID:???
>>237
oを付けると、正規表現中に変数があっても、その正規表現の
コンパイルを最初の一度しか行いません。そのため、
2度目以降のマッチングの際にコンパイルしないぶん早くなります。
なので、通常正規表現中に変数を入れない場合はoをつけとく
方が有利です。

で、正規表現中に変数があって、それが変更される
にもかかわらずoを付けると、当然予期する結果が得られません。
0241かなり初心者02/03/06 22:34ID:+Uo+pWis
ありがとうございました。

助かりました。(^_^;)
0242nobodyさん02/03/06 22:35ID:???
>228
なんだこいつは?
EUCもS-JISも悪。JISに統合せよ,だと?
半角カナもJISが対応していないから使うな,ということなのか。
正直WebページのキャラセットにJISなんて使う気もせんが・・・

http://www2.justnet.ne.jp/~chic/TRON005.HTML
http://homepage1.nifty.com/VET06031/kanaok/kanaok.html
0243nobodyさん02/03/06 22:36ID:???
>>242
でも、漢字コードの判定に失敗しないので便利だよ。
0244nobodyさん02/03/06 22:36ID:???
>240
なるほど!ええこと聞いた!情報ありがとう。

>239
ほんまかいな・・・
foreach(1..100000){}で囲むのか?(笑
0245nobodyさん02/03/06 22:42ID:???
>243
meta で指定すれば問題ないやろ?
024624302/03/06 22:43ID:???
>>245
もちろん。
0247nobodyさん02/03/06 22:46ID:???
>>244
>>239になにか問題が?
0248nobodyさん02/03/06 22:50ID:???
>247
ごめん,今気付いたんだが>237へのレスだと思ってた・・・
変なこと言ってすまん・・・
024924702/03/06 22:57ID:???
>>248
なるー。
0250nobodyさん02/03/06 23:00ID:???
>>244
forにしときなさい。
0251nobodyさん02/03/07 06:18ID:WTUe3Qf1
こっちもage
0252nobodyさん02/03/07 08:50ID:hIR8dzV6
226です。User-Agentってなんですか???
0253nobodyさん02/03/07 09:09ID:???
>>252
http://www.google.com/search?hl=ja&q=CGI+User-Agent&btnG=Google+%8C%9F%8D%F5&lr=lang_ja
0254nobodyさん02/03/07 11:38ID:???
>>253
ありがとうございます。
アクセス制限はこれで出来ますが、携帯でも参照制限(特定のページ)は
可能なんでしょうか?
0255nobodyさん02/03/07 11:39ID:???
>>254
意味が不明。
0256nobodyさん02/03/07 12:18ID:???
>>254
PC初心者板に行きなさい
0257ひよこ名無しさん02/03/07 12:36ID:???
>>256
迷惑。
0258nobodyさん02/03/07 13:23ID:???
>>255,256
意味わかりませんか?User-Agentってようは相手のブラウザを認識するのですよね?
私が聞きたいのはページ(htm,html,texなど)で作成したものに直リンクできない
ようにするための参照制限のことです。
今のところCGI関連のホームページで色々探してみましたが、不可能という答えしか
掲載されていませんでした・・・。
もし知っている方がいらっしゃいましたら教えて下さい。
0259nobodyさん02/03/07 13:29ID:???
>>258
結論出てるじゃん、頼むわ。
0260nobodyさん02/03/07 13:32ID:???
>>258
だから、CGIでページを生成することにして、そのページへ
携帯電話からアクセスしてきたら弾けばいいじゃん。

htmlファイルへのアクセス制限は、CGIとは別問題で、
.htaccessでDoCoMoからのアクセスを拒否するだけだよ。
0261nobodyさん02/03/07 14:04ID:???
>>260
ありがとうございました。

>>259
もしかしたらいい案している人いるかもしれないから
聞いたんじゃん?
代用できる方法知ってるかもしれないし。
私CはわかるけどPerlはさっぱりわからんのじゃ!
初心者なんだから・・・


0262nobodyさん02/03/07 14:11ID:???
最も嫌われる初心者とは、
初心者である事を免罪符のように使う人物である。
0263nobodyさん02/03/07 14:11ID:???
>>261
初心者を盾にするな。
Cが使えるのならその技術で可能か不可能か位は判別出来るだろう。
0264nobodyさん02/03/07 14:21ID:???
しょせんiモードのページ作るヤツなんてドキュンばっかだな。(藁
0265nobodyさん02/03/07 14:24ID:???
>>264
i-modeのページも、あれでいて結構気を使うんだよ。
半角カナにしろだの、ここは絵文字にしろだの、クライアントが
うるさいんだよね・・・
0266nobodyさん02/03/07 14:25ID:???
>>261は20代DQN女性な感じ。

いや、なんとなくだけど。
しかも当たったからと言って何もならないが。
0267nobodyさん02/03/07 14:26ID:???
>>266
何となく納得。
0268 02/03/07 14:47ID:q6SBx/iV
gdbmの詳しい説明があるホームページないですか?
サンプルとか載ってるととっても助かります
教えて下さい。
0269nobodyさん02/03/07 14:49ID:???
初心者がCなんかわかるな。
0270nobodyさん02/03/07 15:36ID:???
>>266
20代女だけど何か?

>>269
CはWEBだけでないでしょ・・・
0271nobodyさん02/03/07 16:32ID:???
全角英数使ってるところがプログラマっぽくないな。
■ このスレッドは過去ログ倉庫に格納されています