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

【Perl 】初心者コーナーPart7

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい01/09/12 13:04ID:???
いらっしゃーい、perlのコーディングで困ってる人のスレです。

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

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

参考書籍はこちら【【Perl,CGI】参考書籍 第2版 】
http://corn.2ch.net/test/read.cgi?bbs=php&key=988809842&ls=50
CGIの質問はこちら【CGIだけど、なんか質問ある?part3】
http://corn.2ch.net/test/read.cgi?bbs=php&key=988727833&ls=50

過去ログ、その他の役立ち情報は>>2-5を見よう。
0155名無しさん@お腹いっぱい。01/09/21 03:05ID:???
>>154
せめて環境くらい書いたらどうだ、ヴォケクァス君!
0156Perl上級者01/09/21 03:07ID:???
>>155のアホ
HP-UXだボケ。
ま、おまえにはわからんだろ(嘲笑)
0157_gunzip@Perl初級者01/09/21 03:10ID:???
>>153-154
(´-`).。oO(仮にもPerl上級者なら、考えるまでもないと思うが・・・)
0158Perl上級者01/09/21 03:14ID:???
>>157
初級者はすっ込んでろ。
0159初心者@Perlなんですが・・・01/09/21 03:29ID:???
ばっふぁ。
0160_gunzip@Perl初級者01/09/21 03:31ID:???
>>158

(´-`).。oO(仰せのままに・・・・)

# fork()が何をするか、どういったバッファリングが行われるか
# 分かっていれば、何も難しくない。
0161名無しさん@お腹いっぱい。01/09/21 03:52ID:???
>>154-160 ふーんなるほど。ひとつ賢くなった。
こんなことないとperldelta読まない俺は逝ってよしですか。
0162あぼーんNGNG
あぼーん
0163Perl上級者01/09/21 04:27ID:???
全然わからん。ちゃんと説明しろ。
素人ども。
0164774301/09/21 04:41ID:0C1HqUNw
UNIXサーバーのcドライブにアクセスしようとする奴になんかいいメッセージをおくってやる方法ねぇかな?
0165_gunzip01/09/21 04:46ID:???
(0) 前提(おおまか)
標準エラー出力以外のストリームは、端末など対話的装置に対しては
行バッファリング(バッファが一杯になるか、改行文字によって書き出す)、
そうでない場合は完全バッファリング(バッファが満杯になって初めて
書き出す)を行う。

(1) ./log.pl の場合

この場合は行バッファリングが行われる。

> print "子プロセスを起動....\n"; (*1)

改行文字により、バッファが標準出力に書き出される。
後はコード通りの(思った通りの)動作をする。

#-------------#
0166_gunzip01/09/21 04:48ID:???
(2) ./log.pl > logfile の場合

この場合、標準出力は端末ではないので完全バッファリングが行われる。従って、

> print "子プロセスを起動....\n"; (*1)

では標準出力に書き出されない。(->バッファへ)その後、

> $pid = fork();

fork()呼び出しによって親のプロセスイメージが複製される際、親の
バッファも同時にコピーされる。(...まあ、大抵"copy-on-write"
だろうけど)
そして、子プロセスがprint "...", exit()した際に

> 子プロセスを起動....
> $message = Hello World

...と、子プロセスのバッファが書き出され、親と子の共有するカーネル空間の
ファイルテーブルのオフセットが更新される。
そして、親は子の死を確認した後、同じくprint "..."; exit()し、更新された
オフセット値から、自身のバッファ

> 子プロセスを起動....
> $message = Hello

を書き出す。...単にこれだけ。

#-------------#

Perl5.6からはfork()の際に自動的に全てのバッファをフラッシュするよう
変更されたため、プログラム作成者の意図通りに(*1)の部分で標準出力
バッファが書き出される。(後の動作は(2)と同じ)
従って、>>153-154のような違いが生じた。
0167774301/09/21 04:49ID:0C1HqUNw
cドライブを探したがるウイルスは、どういう仕組みになってるんすか?
0168_gunzip01/09/21 04:55ID:???
間違えた。
>(後の動作は(2)と同じ)
じゃない。(大体分かると思うけど)

(´-`).。oO(Zzz・・・・おやすみ >>163)
0169Perl初級者01/09/21 05:24ID:???
「バッファをコピー」するからか。
なるへそ。
0170Perl下級者01/09/21 05:36ID:???
>>169
Perl上級者の理解力が急に増したのかと思った。
紛らわしいハンドルつけるなゴルァ

>>164
アクセスしてくるURLと一致するファイルをサーバ上に作れば
いいんでない? "c:"で始まるファイル名で。
0171名無しさん@お腹いっぱい。01/09/21 05:39ID:DP/oQEFM
ここのスレッドの住人て 他にどんな言語が使えるの?
0172名無しさん@お腹いっぱい。01/09/21 09:40ID:5isnB2us
モジュールってなんですか?
どうやってインストールするんですか?
どうやって使うんですか?

なんかモジュールなんて知ってて当然みたいな説明ばかりで
基本的なところがわからない
検索したら、モジュールの作り方とか出てきて涙
0173名無しさん@お腹いっぱい。01/09/21 09:54ID:aEvmZgeQ
>>171
俺は C, PHP, Ruby, Python, ASP(VBScript), ColdFusion を
全て中途半端に使える(w

んで今はJSPの勉強中。

てか一つに的絞って、まずそれを極めろって自分でも思う。

>>172
http://www.google.co.jp/search?hl=ja&q=Perl+%83%82%83W%83%85%81%5B%83%8B+%83C%83%93%83X%83g%81%5B%83%8B&lr=
モジュールの作り方ばかり出てくるか?
0174名無しさん@お腹いっぱい。01/09/21 09:57ID:5isnB2us
あとCPANもよくわかんない。CPANからもってこい、CPANから
ダウンロードしろとか、なんかやっぱりCPANも常識なんですよね?
なんかすげぇバカなこときいてるんだろうなぁ…
0175名無しさん@お腹いっぱい。01/09/21 10:12ID:5isnB2us
>>173
Windowsなんです。なんかモジュール?をダウンロードしたら
Makefile.PLがはいってて、perl Makefile.PLするってのまで
なんとなくわかって、で?みたいな
makeしろと言われてもmakeコマンド?なんてないし・・・

ようやく
ttp://member.nifty.ne.jp/hippo2000/perltips/module_install.htm
にたどりつきました。ちょっと前進かも?
0176名無しさん@お腹いっぱい。01/09/21 10:13ID:5isnB2us
うわ。我ながらすげー頭悪い書き方してるな
でもなんかもうなにがなんだかわかんないんです
0177名無しさん@お腹いっぱい。01/09/21 10:14ID:???
>>171
俺は C, PHP, Ruby, Python, ASP(VBScript), ColdFusion を
全て中途半端に使える(w

んで今はJSPの勉強中。

てか一つに的絞って、まずそれを極めろって自分でも思う。

>>172
http://www.google.co.jp/search?hl=ja&q=Perl+%83%82%83W%83%85%81%5B%83%8B+%83C%83%93%83X%83g%81%5B%83%8B&lr=
モジュールの作り方ばかり出てくるか?
017817701/09/21 10:15ID:???
なんでこんなに遅れて二重投稿(鬱
0179名無しさん@お腹いっぱい。01/09/21 10:30ID:j0KdAUa.
>>174-176
皆おなじ道をたどってきたのさ。。。

WindowsのActivePerlを使ってるなら、CPANからもってくるより
ActivePerlのサイトからPPMつうのでダウンロードするほうが
簡単な場合が多いよ。
ただPPM形式になってるのはメジャーなモジュールだけだから
有名じゃないモジュールはCPANを利用するしかない。

今インストールしてみたいモジュールは具体的に何かあんの?
0180あぼーんNGNG
あぼーん
0181名無しさん@お腹いっぱい。01/09/21 12:32ID:5isnB2us
>>179
ありがとうございます。涙。

今ほしいのは、MP3ファイルのタグを操作(主に読み込み)する
ためのモジュールです。
MP3-infoってのを見つけたのは良いのですが、これを
どうすれば???みたいな状態です。
Makefile.PLがあって、Makefileを作る、ってのは成功したものの、
makeなんて持ってないよ?という
0182a'x ◆5GIjpSRQ 01/09/21 12:48ID:???
>>181
ActivePerlならコマンドプロンプトから

ppm install MP3::Info

ってやればOK。
0183名無しさん@お腹いっぱい。01/09/21 15:09ID:5isnB2us
>>182 ありがとうございます。使っているのはActivePerlです。
さっそく実行してみたところ、
Error installing package 'MP3::Info': Could not locate a PPD
file for package MP3::Info
というエラーになってしまいました。
C:\> ppm install MP3::Info
と、
C:\> ppm
PPM> install MP3::Info
両用やってみました。
0184名無しさん@お腹いっぱい。01/09/21 15:18ID:???
>>181
こちらで一覧見て調べましょう。
http://aspn.activestate.com/ASPN/Downloads/ActivePerl/PPM/Packages
で、PPMPackageはデリミタ(::)指定じゃないです。

見たところありますね。
ppm install MP3-Info でどうぞ。
0185a'x ◆5GIjpSRQ 01/09/21 15:24ID:???
>>183
むぅ。俺はそれでinstall出来たんだが。
ひょっとしてfirewallの中からのアクセス?だったら

set HTTP_PROXY=http://(Proxyホスト名):(Proxyポート)

ってやってppm使ってみて。
0186a'x ◆5GIjpSRQ 01/09/21 15:29ID:???
>>184
>で、PPMPackageはデリミタ(::)指定じゃないです。
そうなの?俺は :: でも出来たが・・・・。(今試したら、- でも出来た)
0187_gunzip01/09/21 17:35ID:???
VineLinuxにActivePerl入れて試してみたけれど、::でおっけいだったよ。

というか、ppmは中で
$package =~ s/::/-/g;としているから、デリミタの問題ではなくてtypoか何かじゃないかなあ。
0188名無しさん@お腹いっぱい。01/09/21 18:44ID:nYoU2cMw
ファイルロックではどんなのがありますか?
普通はflock使いますか?
0189名無しさん@お腹いっぱい。01/09/21 18:49ID:???
うん。
0190名無しさん@お腹いっぱい。01/09/21 19:03ID:TAJp9wyQ
JavaScriptで、onload=で複数のスクリプトは起動できないの?
できるとすればどうやって書けばいいの?
0191名無しさん@お腹いっぱい。01/09/21 19:33ID:???
板違い。
0192名無しさん@お腹いっぱい。01/09/21 19:35ID:TAJp9wyQ
失敬パールだった。
0193名無しさん@お腹いっぱい。01/09/21 20:36ID:RIYGknmQ
>>184-186 わーーーーー。入った。入りました。
ありがとうございます。typoだったのかな?
とにかく嬉しい! 感謝感激です。
0194名無しさん@お腹いっぱい。01/09/21 20:42ID:ziETu.IM
Apache::Sessionなんですが、
セッションのタイムアウトを実現するために、
Apache::Session::MySQLでセッションテーブルに
TIMESTAMPフィールドを置いて、cronでスクリプト走らせて
一定時間以上前のものを削除しています。
こういうようなことを、Apache::Session::DB_Fileでやるには
どうしたらいいんでしょう?
0195名無しさん@お腹いっぱい。01/09/21 20:43ID:???
>>184-187 でした。番号間違い。すみません。
さーがんばるぞー!
0196名無しさん@お腹いっぱい。01/09/21 21:11ID:???
>>187
PPM見たけど、s/::/-/な部分が見当たらなかった。
ポインタ示していただけるとありがたいです。
0197_gunzip01/09/21 22:11ID:???
>>196
あ、もしかしたらWindows版のppm.batを見ていませんか?

$ grep "s/::/-/" -n /usr/local/ActivePerl-5.6/bin/ppm
111: s/::/-/g;
164: $package =~ s/::/-/g;
190: $package =~ s/::/-/g;
0198a'x ◆5GIjpSRQ 01/09/21 22:42ID:???
>>196
Win版なら
C:\Perl\bin\ppm
の107行から(バージョンにより行は多少変わると思うが)
for (@ARGV) {
s/::/-/g;
}
と有ります。ppm.batにも同様に120行から
for (@ARGV) {
s/::/-/g;
}
と有ります。
0199あぼーんNGNG
あぼーん
020019601/09/21 23:37ID:???
>>197-198
ありがとう。
自分、CygwinPerlでしかも入れてないんで、
PPM-*.tar.gz持ってきてその中身見てました。
020114901/09/22 04:45ID:ZYiZZlao
>>152
レスおそくなっちゃいましたけど。
わざわざありがとうです。
0202マヌケ初心者01/09/22 05:32ID:gUO1IwS2
すみません
apeボードのスキンを作っているのですが
強制改行させるにはどうしたらいいのでしょうか?
幅500の別ウィンドウに板を表示させてるのですが
改行せずに書き込まれるとマヌケに横に伸びてしまいます
そんな事もしらない俺がマヌケなのは重々承知しています
どなたか教えて頂けませんでしょうか?
宜しくお願い致します
0203名無しさん@お腹いっぱい。01/09/22 06:05ID:???
>>202
それってスキンでスタイルシート使うとかして、なんとかならん?
apeボードのスキンって、そういうもんじゃないんすか。よく知らないけど。

まあ諸事情でどうしてもCGIを改造する必要があるというなら、
このサイト↓などを参考に。
http://www.din.or.jp/~ohzaki/perl.htm#JP_Fold
0204名無しさん@お腹いっぱい。01/09/22 09:14ID:YFImM5JM
初歩的でごめんなさい。

Perlでスクリプト書いて、ファイル名の拡張子を
「.pl」と「.cgi」どちらにしたらいいんですか?
どちらでも一応同じ動作をするんですが・・。
何か使い分けなんでしょうか・・・・汗
0205名無しさん@お腹いっぱい。01/09/22 09:30ID:???
>204
サーバーによる。
サーバーの関連付けの設定で「.pl」でCGIが起動できない所もある。
そういう事があるから、閲覧者が直接参照する方が「.cgi」で、
ライブラリとかが「.pl」なんじゃないかと俺は考えてる。
あくまで憶測。
0206マヌケ初心者01/09/22 09:47ID:1q1.uifg
>203
レスありがとうございました
おっしゃる通りスキンでなんとか・・と思ったのですが
widthで幅きめても結局書き込む時に改行されなかったら
横にのびちゃうんですよ
色々調べ回って他のテスト板試してみたんですが
どれも伸びてました(w
紹介して頂いたサイト見てきます
ありがとうございました。
020720401/09/22 10:02ID:???
>205
ありがとうございます。
少しずつ勉強したいと思います
0208名無しさん@お腹いっぱい。01/09/22 12:11ID:EJpCVqks
<list>
<data>〜</data>
<data>〜</data>
…
</list>
というデータをXML::Generatorで作ろうと思っています。
与えられたデータ1行→<data>〜</data>に変換、で、
print "<list>"\n
while(<>){
my $xml = new XML::Generator;
$xml->data(…);
}
print "</list>"\n
のような処理を考えたのですが、これで良い物でしょうか?

不安なのは、while()の中でnewして良いのかなぁ?
freeとかってしなくてよいのかなぁ?という点です。
#根本的にかっちょわるいことしてたらやだなぁとも思う
0209名無しさん@お腹いっぱい。01/09/22 16:17ID:???
>>208

ガベージコレクターがあるので問題なし。
ちなみに new なら delete でしょ?
0210名無しさん@お腹いっぱい。01/09/22 16:24ID:EJpCVqks
>>209
なるほど。そうだったのですか! それなら安心です。
そして、newに対応するのはdeleteなのですね。恥。
0211-01/09/22 16:41ID:X9qGQ5PU
その画像ならココ
http://members.tripod.co.jp/bingo852/
0212名無しさん@お腹いっぱい。01/09/22 16:43ID:???
ディレクトリ下(含サブディレクトリ)にある全ての*。htmlを
パス名付きで取得するにはどうやるんでしょうか???
0213名無しさん@お腹いっぱい。01/09/22 16:44ID:???
>>212 自分の番号をアドレスに入れようとして失敗
0214名無しさん@お腹いっぱい。01/09/22 16:58ID:u4MHoQsY
モジュールがインストールされているかどうか調べるのって
どうやるんでしたっけ?

perl -e 'use LWP::UserAgent;'
とかやってエラーなければインストールされてるって判断して
いいんでしょうか?
0215名無しさん@お腹いっぱい。01/09/22 17:55ID:bcGEWw7s
今WindowsにPerl入れて勉強してるんですが
Windows上で動かしているとflockとか使用できませんよね
flock以外にもWindows上だと使用できないものってありますか?
0216名無しさん@お腹いっぱい。01/09/22 17:56ID:???
たくさんあるんじゃない
0217名無しさん@お腹いっぱい。01/09/22 18:12ID:UPWBdois
>216
Windows上のPerlとかでsubstrとかって使えんの?
0218名無しさん@お腹いっぱい。01/09/22 18:18ID:.Ro0S1Bw
大文字小文字を区別しないでソートする処理を
一行で書くにはどうすればいいですか?
0219名無しさん@お腹いっぱい。01/09/22 18:22ID:???
>>211
use File::Find;
find sub { push @list, $File::Find::name }, ".";

>>214
perl -MLWP::Simple -e 'print $LWP::Simple::VERSION'
perldoc LWP::Simple
等。

>>215
WinNT/2000ではflock使える。
環境限定されるものは他にもある。

>>217
問題無い。
0220名無しさん@お腹いっぱい。01/09/22 18:23ID:B3IfreL6
>>217
やってみればいいじゃん
0221名無しさん@お腹いっぱい。01/09/22 18:29ID:???
>>211
use File::Find;
find sub { push @list, $File::Find::name if /\.html$/ }, ".";

>>218
map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [$_, lc] } @list;
0222名無しさん@お腹いっぱい。01/09/22 18:34ID:???
>.221 ありがとう。想像してたよりムズカシー
0223名無しさん@お腹いっぱい。01/09/22 19:38ID:u4MHoQsY
htmlから <img src="〜">を探してリストにするというスクリプトを
作ろうとしているのですが、長いページになると止まってしまいます。
正規表現で扱える文字長って最大値が決まってるのでしょうか。

while( $str =~ /(<img [^>]*src="?)([^"]+)("?.*?>)/isg ){
 $tag1 = $1;
 $img = $2;
 $tab2 = $3;

 $str =~ s/$tag1$img$tag2//i;

 print $img. "\n";
}

1行1行処理すれば問題ないのですが、
<img
src="〜">
というようなものもあるので
022422301/09/22 19:48ID:u4MHoQsY
>>223
すいません

while( $str =~ /(<img [^>]*src="?)([^"]+)("?.*?>)/isg ){
じゃなくて
while( $str =~ /(<img[ \r\n][^>]*src="?)([^"> ]+)("?.*?>)/isg ){
ですね。最初の<imgから最後までひっぱってた。^^;

馬鹿長いページでエラーが起きるのは同じです。
 
0225名無しさん@お腹いっぱい。01/09/22 19:50ID:???
>>219 >>221
ありがとうございます!!! 感激っす!
0226名無しさん@お腹いっぱい。01/09/22 21:01ID:???
>>223
それの原因はわかんないけど
タグ抜き出しツールを作るならHTML::Parserつーのも便利。

use strict;
my $file = "hogehoge.html";
my $parser = MyParser->new;
$parser->parse_file($file);

package MyParser;
use base 'HTML::Parser';
sub start {
my ($self, $tag, $attr, $attrseq, $text) = @_;
if ($tag =~ /img/i) { $text =~ tr/\r\n//d; print "$text\n"; }
}
0227名無しさん@お腹いっぱい。01/09/22 21:29ID:???
>>226
おぉ、そんなものがありますか。感謝です。

ついでといってはなんですがディレクトリを扱うのに便利な
モジュールってありますでしょうか。
たとえばサブディレクトリを一度に削除できるようになるやつとか。

通常だと最下層から順番にやっていかなきゃいけないから。(´∈ ` )
0228名無しさん@お腹いっぱい。01/09/22 21:43ID:???
>>227
use File::Path;
rmtree($root, 0, 0);
0229名無しさん@お腹いっぱい。01/09/23 00:45ID:SMJO237A
>>228
なるほど、File::Pathでしたか。
せんきゅですっ!
0230_gunzip01/09/23 01:07ID:???
>>223-224
についてコメントした方がいいかな...どうだろ。
0231まなぶくん01/09/23 01:13ID:???
もちろんですっ!
0232名無しさん@お腹いっぱい。01/09/23 01:25ID:???
>>230
色んなアプローチを示すのは良い事だと思うが。
0233_gunzip@眠い01/09/23 01:47ID:???
あ...寝るところだった。

>>223-224さんの言う
>長いページになると止まってしまいます。
というのは、およそ二つの原因があるんじゃないかと。

例えば、下のスクリプトが何故"*"ではなく"**"と表示するのか...とか。
-------------------------------------------
#!/usr/local/bin/perl

our $string = "<<tag>tag>";

while($string =~ /<tag>/g){
    $string =~ s/<tag>//;
    print "*";
}
print "\n";
-------------------------------------------
0234_gunzip@ぼけ01/09/23 01:51ID:???
>例えば、下のスクリプトが何故"*"ではなく"**"と表示するのか...とか。

...って当たり前だな。眠いけどまとめてみます。
0235名無しさん@お腹いっぱい。01/09/23 02:00ID:uXqIVwdQ
$/ = "<";
s/^img //i and push @imgs, /src="?([^"\s])"?/i while (<>);
とか。
0236腐ったソース大好き01/09/23 02:02ID:uXqIVwdQ
$/ = "<";
while (<>) {/^img /i and push @imgs, /src="?([^"\s]+)"?/i }
か
0237まなぶくん01/09/23 02:09ID:???
んー、、ラストインなんちゃらでしたっけ
この手のは何時も試行錯誤で結果オーライなんだよなー
_gunzipさんはエンジンのソース読んでるんだろな・・・
(´-`).。oO(あたまいたい。。。)
0238まなぶくん01/09/23 02:10ID:???
あ、糞レスだ。 ありがとッス、考えて見るッス
(´-`).。oO(ってまた糞レスだ。。)
0239名無しさん@お腹いっぱい。01/09/23 02:24ID:???
すみません。みなさん。
アパッチでperlを動かすには
どのような設定が必要なのでしょうか?
0240名無しさん@お腹いっぱい。 01/09/23 03:10ID:???
漠然としすぎ、つーかしばらくコマンドで遊べよ。
そんな感じで追加質問が延々と続くパターンはたまらんよ
簡単に言うと
httpd.confってファイル弄ってexecCGIするんだ
検索すれ
0241名無しさん@お腹いっぱい。01/09/23 03:35ID:???
>>239
Apacheで[Perl]が動くって・・・。
別にPerlがインストールされていればApacheの有無に関係ないですけど。
CGIならスレ違いだかんね。

# ここんとこperlの質問で良い感じに流れてる気がする。
0242名無しさん@お腹いっぱい。01/09/23 03:51ID:EZbM3lIs
>239
検索すればすぐに出てくるからおとなしくgoogleでも逝ってなさい
024323901/09/23 05:41ID:???
具体的に言うと
httpd.confの
設定はどうすればいいか?
です。

でもここはperl言語についてのようなので、スレ違いのようですな。
0244名無しさん@お腹いっぱい。01/09/23 06:18ID:???
みなさん。
ありがとうございました。
httpd.confにExecCGIをつけて動きました。

ありがとうございました。m(_ _)m
0245名無しさん@お腹いっぱい。01/09/23 11:43ID:IRukl05.
Windows上のPerlで下記の簡単なスクリプトを動かそうとしているのですが
動きません。間違ってはないと思うのですが・・・
unlink("*.*");
rmdir("*.*");


print"Content-type:text/html\n\n";
print<<EOF;

<html>
<head>
<title>デリート</title>
</head>

<body>
<BR><BR><BR><CENTER>
消しちゃいました〜(゚▽゚=)ノ彡☆ギャハハ!!
</CENTER>

</body>
</html>

EOF

exit;

上の方にもありますがWindowsME上のPerlではunlinkが使えないって
ことはないですよね?
それともunlinkとかrmdirに*って指定できないんですか?
とっても初心者な質問ですがお願いします。
024624501/09/23 12:19ID:IRukl05.
補足ですが下部のHTML部分は付け足しただけですので実際に使うときは
HTML部分はありません。
0247名無しさん@お腹いっぱい。01/09/23 12:46ID:???
ワイルドカードなんて使えたっけ?
0248名無しさん@お腹いっぱい。01/09/23 12:56ID:???
globなら使えるけどね。他は無理でしょ。
0249名無しさん@お腹いっぱい。01/09/23 13:11ID:???
というわけで>>245は
unlink(glob('*.*')); または unlink(<*.*>);
に修正しる。
0250_gunzip01/09/23 14:34ID:???
while() 内はboolコンテキスト(スカラーコンテキストの一種)で評価されるため、
m//gは前回マッチした位置をmagicメンバ(これはリンクリストとして実装されている。)に記憶しておき、次回からはそのオフセットから検索を開始する。
マッチに失敗するか、文字列の内容に対する破壊的動作(代入その他)が行われた場合などは、オフセットを文字列の先頭に巻き戻す。
このことを知っていれば、
-------------------------------
our $string = "target string";

while($string =~ /target/g){
    my @a = ( $string =~ /another/g );
}
-------------------------------
が無限ループになることがすぐに分かる。

例えば、>233のスクリプトで実際のところ何が起こっているかというと、
(下の[][]..[]はメモリ内のイメージ。('\0'は除く)offsetはSv-PVMGのIVスロットの値、
lengthはlenメンバ、matchはmagic.mg_lenメンバのこと。)
--------------------------------------------------------
| $string = "<<tag>tag>";
--------------------------------------------------------

$string = ['<']['<']['t']['a']['g']['>']['t']['a']['g']['>']
| offset = 0 #バッファ領域内の文字列開始オフセット
| length = 10 #文字列の実際の長さ
| match = -1 # $stringに対するマッチの開始オフセット

% メモリ確保のオーバーへッドを抑えるためにPerlは予め余分に
% バッファを確保するが、ここでは割愛する。
-------------------------------------------------------

-------------------------------------------------------
| while($string =~ /<tag>/g){ # 一回目のループ開始
-------------------------------------------------------

$string = ['<']['<']['t']['a']['g']['>']['t']['a']['g']['>']
| offset = 0
| length = 10
| match = 7 #次回のマッチ開始位置が更新される

% $string の2-6文字がマッチしてリターンする。
-------------------------------------------------------
0251_gunzip@今頃起きた01/09/23 14:36ID:???

-------------------------------------------------------
| $string =~ s/<tag>//;
-------------------------------------------------------

$string = ['<']['<']['t']['a']['g']['<']['t']['a']['g']['>']
| offset = 5 #更新される。上の6セル目に注目。
| length = 5 #当然短くなる。
| match = -1 #オフセットがリセットされる

% s///による置換。
% s///によって部分文字列が削除される際、Perlはマッチした個所の
% 文字列における位置を調べて、バッファを移動させる量が少ない方を採る。
% この場合、マッチしなかった先頭文字の'<'を5バイト後ろにずらし、
% バッファ先頭からの文字列開始オフセットを5に設定する。
% また、マッチの開始オフセットがリセット(-1)され、次のwhile()
% ループのマッチは、文字列の先頭位置から始めることになる。
-------------------------------------------------------

-------------------------------------------------------
| while($string =~ /<tag>/g){ #二回目のループ開始
-------------------------------------------------------

$string = ['<']['<']['t']['a']['g']['<']['t']['a']['g']['>']
| offset = 5
| length = 5
| match = 5 #次回オフセット(文字列終端)

% matchの値に従い、**文字列の先頭から**検索を開始し
% マッチは(始めの予想に反して)成功する。
------------------------------------------------------
0252_gunzip01/09/23 14:38ID:???
よく寝た....もう昼じゃん。

>>223さんの「非常に遅くなる」というのは、理由が二つ考えられるけど、
((( っていうか、なぜs///の部分が入っているのかなあ.....。
....もしかして、while($string =~ /pattern/g) だと、前回マッチした部分文字列が
残っているので、次回もその部分がマッチし無限ループになるのではないかと思ったのかな?
それで、s///でその部分を取り除いておかなくては、と考えたのだろうか?
もしそうなら、m//gはスカラコンテキストでは前回のマッチ位置を記憶しておいて
次回はそこから検索開始するので,while()内にいれても特に問題はないってことは
知っておいて欲しいな。 )))

>長いページになると止まってしまいます。
から思うに、(余計な)s///の副作用(*注)で毎回検索開始位置がリセット(上の例参照)
されるため、毎度文字列の初めからマッチを開始せねばならず、また、置換に伴う
バッファの移動も大量に行われるようになる。その結果、ファイルが大きくなるにつれて
莫大な時間がかかるようになる、というのが原因の一つ。

(*注) $stringへのs///, 左辺substr(),代入などの破壊的操作だけではなく、
単なるm//gパターンマッチだけでもwhile()内のm//g検索オフセットはクリアされる。
0253_gunzip@昼飯01/09/23 14:51ID:???
他の原因として考えられるのは、
$strに対して、さらに何か手を加えている。#-->無限ループ
| pos($str) = 0 #オフセットを明示的にリセット
| substr($str,0,0) = "hoge"
| $str .= "text"
while()ループ内のs///に'g'修飾子が付いている。#->無限ループ
$str内に'\n', '\w', '\G' 等のキャラクタがあり、s///の所でなにか副作用でも起こしている。
#-->データ見ないことには判断できない。

けつろん
while($string =~ /PATTERN/g)ループの中での$stringの扱いには少し注意して欲しいなあ、
ということです。(単なる読み出しは全く問題なし)
っていうか、>>223の場合は6行めのs///を削除すればいいだけのような。
(結局言いたいことはこれだけ.....)

--------------------------------------------
ちなみに、自分はHTML::LinkExtorモジュールの利用を勧めておきますね。

#!/usr/bin/perl

use HTML::LinkExtor;

HTML::LinkExtor->new(\&ext)->parse_file('./index.html');

sub ext
{
     my($tag, %attr) = @_;
    if( lc($tag) eq 'img' ){
         print $attr{src} , "\n";
    }
}
0254_gunzip01/09/23 14:57ID:???
順番狂ってる....。

our $string = <<'END_OF_STRING';
<img src="/usr/local/pixmap/title.png">
<img
src="./cap.gif">
END_OF_STRING

while($string =~ /<img[^>]+?src\s*=\s*["']?([^'" >]+?)[ '"]?>/gis){
    print $1, "\n";
}
0255名無しさん@お腹いっぱい。01/09/23 17:20ID:???
>>250-254
なるほどねぃ。
ためになる話をありがとう。
■ このスレッドは過去ログ倉庫に格納されています