【Perl】初心者コーナー Part18
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
02/11/20 22:04ID:???1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。
1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
CGIだけど、なんか質問ある? Part 8
http://pc.2ch.net/test/read.cgi/php/1032704121/
参考書籍の話題は【Perl,CGI】参考書籍 第三版
http://pc.2ch.net/test/read.cgi/php/1030209573/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般/Part2】
http://pc.2ch.net/test/read.cgi/php/1030548610/
スクリプトの改造依頼は 【 スクリプト改造工房 PART 5 】
http://pc.2ch.net/test/read.cgi/php/1028193595/
過去ログ、その他の役立ち情報は>>2-10あたりを見よう。
0175nobodyさん
02/12/03 01:13ID:???if($day < 10){$day = "0$day";}
なんて方法は最悪の部類ですよ。かなりひどい本だと
断定してもいいです。たぶんこれもkent-webのソース
をダサいままぱくってるのかな?
0176nobodyさん
02/12/03 01:18ID:ZhYTYd9Tデータファイルを読み込んで、任意の数字がある場合のみprintしたいと思っています。
for(@log){
if($_ =~ /$num/){
print "$_";
}
}
これでやると、$num=10;とした時、100や101、102....もマッチしてしまいます。
10なら10だけをマッチさせたいのですが可能でしょうか?
0177nobodyさん
02/12/03 01:27ID:???後で必要なのは$timeだけだよね?
($min, $hour, $day, $mon, $year) = (localtime time)[1..5];
$time = sprintf "%s, %02d-%s-%d, $02d:%02d".
qw(Sun Mon Tue Wed Thu Fri Sat)[$wday], $day,
qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)[$mon],
$year+1900, $hour, $min;
0178nobodyさん
02/12/03 01:29ID:???区切り文字とかってないの?どんなデータファイル?
いちおう /\D$num\D/ で可能だとは思うが
行頭と行末の場合はヒットしないので注意。
0179176
02/12/03 01:44ID:???データファイルは掲示板の書き込みのような文章です。
その文章中(記事番号とかではなくて)に任意の数字がある場合にマッチさせたいのです。
/\D$num\D/を使ったらうまくいきそうです。
ありがとうございました。
0180nobodyさん
02/12/03 02:26ID:???$t = localtime;
print $t, "\n";
0181nobodyさん
02/12/03 13:18ID:???前スレでおしえてもらったのを使いつつやってみてるんですが、、、
perl書くの初めてなんで全然分からず行き詰まり。どなたか助けてください。
my $output = "aaa.html";
open (OUTPUT, ">$output") || die "Could not open file $output : $!\n";
print OUTPUT "(HTMLヘッダ部〜<table>まで)";
print OUTPUT "<tr><th>No.</th><th>filename</th><th>update</th></tr>\n";
my $now = time;
my %files;
opendir(DIR, '.');
while (readdir(DIR)) {
if (($_ =~ /.txt$/i) && ($_ ne "readme.txt")){
$files{$_} = (stat($_))[9];
}
}
closedir(DIR);
0182nobodyさん
02/12/03 13:18ID:???foreach $key (reverse sort {$files{$a} <=> $files{$b}} keys %files) {
# このへん分からない
my $last_date = $files{$key};
my $ptime = int(eval(($now - $last_date)/86400));
$title = $key;
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($last_date);
$year = eval($year + 1900);
$mon = eval($mon + 1);
substr($title,-4,4) = "";
print OUTPUT "<tr>\n<td align=\"center\">$i</td>\n";
print OUTPUT "<td>$title</td>\n";
print OUTPUT "<td align=\"center\">$year年$mon月$mday日</td>\n</tr>\n";
# ??
}
(以下続きがある予定)
print OUTPUT "(タグ閉め)\n";
close (OUTPUT);
0185nobodyさん
02/12/03 15:16ID:???>print OUTPUT "<tr>\n<td align=\"center\">$i</td>\n";
の行はいらないんで、$iは無視してください。
sortしたのをforeachでちゃんと回るようにしたいんですが。
0186nobodyさん
02/12/03 18:16ID:???新しい順に並ばないか?
0188nobodyさん
02/12/03 21:12ID:???プログラミングPerlを買ってきて読め。
それで全て解決。
0189184=186
02/12/03 22:07ID:???このスクリプトなら新しい順に並ぶでしょう?
並ばないなら、どうなるのか教えて欲しい。エラーが出るのか?
で、最終的にどうしたいわけよ。
%filesにどんな値が入るか観察してみるとわかるかもな。
実行して生成されるhtml見ると、この部分(foreach(){ }の中)が抜けてて、
ヘッダとフッタの部分だけになっちゃうんで。。
0191nobodyさん
02/12/03 23:23ID:lLuHX1/s$time(10桁の数値)を出来るだけ少ないバイト数に可逆圧縮したいのですが、
どうすればよいでしょうか。
例えば16進数で表記すると、
1037797479(10byte) → 3DDB8867(8byte)
で2byte縮むことになります。
ただ、圧縮後の数値は aタグにのせてリンクするので、(<a href=test.cgi?i=3DDB8867>)
URLに使えない文字だと駄目なのですが。
よろしくお願いします。
0192nobodyさん
02/12/03 23:33ID:???そんなことをする意味は……それは言わんでおくか。
URLに使える文字のテーブルを作って、仮にそれが50個あった場合は
timeの数値を50進数に変換したあと、テーブル引いて文字化する。
受け取る側では逆のことをやる。これなら5〜6文字ぐらいにできるんでない?
0194nobodyさん
02/12/04 00:01ID:???ありがとうございます。
目的は携帯サイトの2k制限を如何にクリアするか、ということなんです。
その為にHTMLに出力する部分は出来るだけ文字数を落としたいのです。
(0..9,a..z,A..Z,_,-)
仕様上URLでそのまま送れる文字は上記と、'.'、'*'だけみたいですので、
そうなると64進数が限界でしょうか。。
ご意見ありがとうございました。
0196nobodyさん
02/12/04 00:14ID:???あ゛あ゛あ゛恥ミス発見!
ご指摘の通り $time = time; でした。
64^4 = 16777216
で、10桁は表現できないと思うのですが・・
4バイトで表現するにはどうしたらいいんでしょうか?
0197189
02/12/04 00:23ID:???おお。すまん。
foreachと言うのでそこばかり気にしていたよ。
while (readdir(DIR)) {
を>>193のように
foreach(readdir DIR){
とするか
while($_ = readdir DIR){
としてみれば解決すると思うぞ。
0198nobodyさん
02/12/04 01:33ID:???1970年のデータが必要かどうか判りませんが、
もし最近のものならその数字(timeの戻り値)自体を減らしてみてはどうでつか?
$time = time - 946684800;
2000年01月01日午前00時00分00秒を0とするとか。
0199nobodyさん
02/12/04 01:33ID:???>>195は、timeの値が4バイトだと言ってる。つまり32ビット。
で、64通り=6ビットの場合、6文字必要。
でも、何十年も使う訳じゃないだろうから、timeから1000000000を
引いた値を5文字(30ビット)で格納、でどうかな。
0200199
02/12/04 01:34ID:???1時間前のカキコに…笑
0201181
02/12/04 09:10ID:???0202196
02/12/04 11:17ID:???なるほど!理解できました。
確かに最近のものだけなので、timeの戻り値を減らしてみます。
この度はどうもありがとうございました。
またよろしくお願いいたします。
0203nobodyさん
02/12/04 15:23ID:???for (1..10){
print "うんこ\n";
}
こういう書き方はありですか。
0205nobodyさん
02/12/04 18:01ID:7+5xaubmlinuxの設定ファイルでよくある「.conf」ってなにか規格があるの?
perlから簡単に扱えるようなモジュールはありますか?
0206nobodyさん
02/12/04 20:05ID:???意味があまりよく判りませんが、「.pl」や「.cgi」など、AddHandlerで設定した拡張子にしておくと、直接ブラウザで見られたときに、エラーが返ってくるので安心かもしれません。
0207nobodyさん
02/12/04 20:41ID:???Windowsでいうところの.iniやMac OS Xでよく使われているようなplist
みたいに、設定ファイルのデファクトスタンダードな規格はあるのか?
ってことでしょ? 無いと思う。
CPANにいけば、設定ファイルをごにょごにょするモジュールはいっぱい
あるので、検索してみることをお勧め。
0208nobodyさん
02/12/05 02:20ID:???ここに有るものを好きに選ぶよろし
http://cpan.org/modules/by-category/02_Perl_Core_Modules/Config/
02091/2 長文すいません。。
02/12/05 04:48ID:jP9xslt3timethese(1000, {
foreach => sub {
open(FILE, '/test.data');
my @data = <FILE>;
close FILE;
foreach (@data) {
tr/E//;
s/a/e/g;
}
},
while => sub {
open(FILE, './test.data');
while (<FILE>) {
tr/E//;
s/a/e/g;
}
close FILE;
},
});
}
02102/2 長文すいません。。
02/12/05 04:48ID:jP9xslt3foreach: 2 wallclock secs ( 0.19 usr + 1.21 sys = 1.40 CPU) @ 713.78/s (n=1000)
while: 2 wallclock secs ( 0.46 usr + 1.72 sys = 2.18 CPU) @ 457.88/s (n=1000)
Benchmark: timing 1000 iterations of foreach, while...
foreach: 1 wallclock secs ( 0.22 usr + 1.12 sys = 1.34 CPU) @ 745.71/s (n=1000)
while: 2 wallclock secs ( 0.55 usr + 1.59 sys = 2.14 CPU) @ 466.42/s (n=1000)
Benchmark: timing 1000 iterations of foreach, while...
foreach: 1 wallclock secs ( 0.21 usr + 1.19 sys = 1.40 CPU) @ 713.78/s (n=1000)
while: 3 wallclock secs ( 0.52 usr + 1.71 sys = 2.23 CPU) @ 447.63/s (n=1000)
foreach の方が速いんですけど、Benchmark の使い方間違っていますか?
この2つではよく while を使えといわれますが、それは速さではなくて別の要因があるからなんでしょうか?
配列にいれると大きなファイルだとメモリを圧迫するとか。
whileで回すとその心配はないのかな?
0211209-210
02/12/05 04:51ID:???やっぱりwhile のほうが速いですね・・・・。
すいませんでした。。
0213正規表現・・・・
02/12/05 13:08ID:vPIO4lyL$test =<<"TEST";
ここから始まりです。
<FOO>
hogehogehoge
hogehogehoge
hogehogehoge
</FOO>
ここで終わりです。
TEST
という文字列から<HOGE>から</HOGE>までを抜き出したい場合。
Perlでどんな風にかきゃいいんでしょう?
正規表現道場過去ログには
m[<FOO>.*?</FOO>]sのようにすればイイみたいな事が書いてあるんだけど
$test =~ m[<FOO>.*?</FOO>]s;
print $test;
てな感じでやってみると、$testはなにもされてません。
0214nobodyさん
02/12/05 13:14ID:???print $1;
0215nobodyさん
02/12/05 13:15ID:???print $1;
0216正規表現・・・・
02/12/05 13:31ID:vPIO4lyL感謝です。
0217nobodyさん
02/12/05 15:55ID:34DLd1c6ファイルオープンでエラーが出た場合に
処理を続行したいのですがエラーをクリアーする
関数などはあるのでしょうか?
また、読み込みの場合でもファイルロックをかける必要は
あるのでしょうか?
0218nobodyさん
02/12/05 16:19ID:???> 処理を続行したいのですが
開けなかった場合中断するってな風にプログラムしてなきゃ普通に処理を続行しますが。
>また、読み込みの場合でもファイルロックをかける必要は
>あるのでしょうか?
読み込みしかしないファイルなら必要ありません。
更新されるファイルならした方がよいでしょう。
0219nobodyさん
02/12/05 16:58ID:34DLd1c6勉強になりました
0220nobodyさん
02/12/05 18:12ID:x3XgL2vWJcode.pmをniftyで動かす方法を、教えていただけないでしょうか。
0221nobodyさん
02/12/05 22:49ID:???#!/usr/local/bin/perl -T
とするとエラーになって動作ません。
原因としてどんなことが考えられるのでしょうか?
0222nobodyさん
02/12/05 23:03ID:qFEbS8pnこれってプロバイダに言えばインストールしてくれるもんでしょうかね?
諦めて自宅鯖にしたほうがよいですかね?
0223nobodyさん
02/12/05 23:07ID:???Niftyは標準モジュールも入ってないし無理じゃない?
>>221
Tオプションの意味が分かるなら答えもおのずと分かりそうなモンですが。
>>222
プロバイダによってポリシーが違うだろうし、プロバイダに聞けとしか言いようがない。
0227nobodyさん
02/12/05 23:17ID:???エラーメッセージぐらい書いても罰あたらんだろうに。
0228nobodyさん
02/12/05 23:20ID:???0229nobodyさん
02/12/05 23:27ID:???1:自分はこう言う事がしたい。
掲示板のフォームから送られてくるデータの汚染チェックをしたい。
2:それでこんな風にやってみたが・・・
#!/usr/local/bin/perl -T
としてみた。
3:それだとこんなエラーが出て上手く行かなかった。
The script did not produce proper HTTP headers.
Please see the error log to see the detail of the errors.
あと226は多分漏れじゃない誰かです。
0230nobodyさん
02/12/05 23:39ID:???Please see the error log to see the detail of the errors.
適切なHTTPヘッダを吐いてない。
エラーの詳細はエラーログで見れ。
って書いてるじゃん。
0232nobodyさん
02/12/06 00:35ID:???MODULEしか使わないのですが、require 'aa.pl' と use MODULE; では速度や
負荷は変わらないですか?
aa.plの内容
#------↓ここから
packege MODULE;
・・・
1;
package MODULE2;
・・・
1;
#------↑ここまで
0233nobodyさん
02/12/06 00:41ID:???0234nobodyさん
02/12/06 00:46ID:???aa.plをuse MODULE;では呼び出せないと思うが。
0235232
02/12/06 00:50ID:???a.pm
--------------------
package MODULE;
・・・
package MODULE2;
・・・
1;
-------------------
b.pl
-------------------
use MODULE; # または require 'a.pm';
# MODULE2は使用しない。
0236nobodyさん
02/12/06 01:07ID:???use a;
になると思うのですが。
でOOPなら
$hoge1 = new MODULE;
$hoge2 = new MODULE2;
$a = $hoge1->hoge( $xxx );
とかに
単に関数を呼び出すだけなら
$a = MODULE::hoge();
$b = MODULE2::hoge();
0238nobodyさん
02/12/06 01:38ID:???1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。
1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
0239nobodyさん
02/12/06 01:40ID:???余計なの読まないから良いんでない?
サブルーチンをインポートする必要がなければ、だけど。
あとは大差無いかと。
0240nobodyさん
02/12/06 07:37ID:???0241nobodyさん
02/12/06 11:46ID:yzLDpzsK@values = split(/■/, $aiueo);
$i = 0;
foreach $value (@values){
if($value eq ""){
@values[$i] = "NULL";
}
print "$i : @values[$i]\n";
$i++;
}
これを実行すると、
0 : 1
1 : 2
2 : NULL
3 : NULL
4 : 3
5 : 4
こう表示されます。
しかし、最後の5以降はsplitでは無視されてしまうようです。
自分としては
0 : 1
1 : 2
2 : NULL
3 : NULL
4 : 3
5 : 4
6 : NULL
7 : NULL
8 : NULL
としたいのですが可能でしょうか。
0242nobodyさん
02/12/06 12:01ID:???ものすごく安易な解ですがsplitする前に
$aiueo .= "EOL";
とかで後ろに文字をくっつけておいて、
splitした後にpopしてやると逃れることは
できます。
$aiueo = "1■2■■■3■4■5■■■";
$aiueo .= "EOL"
@values = split(/■/, $aiueo);
pop @valures;
$i = 0;
という感じです。
0244nobodyさん
02/12/06 12:20ID:q7PjCrztサーバに保存するファイル名に投稿された時間を反映させるには(img200212061220.jpgのように)、
どのような記述が必要ですか?
0245nobodyさん
02/12/06 13:24ID:???スクリプトを見ないとわからん
こんな感じで作った文字列をファイル名につけてやりゃいいんじゃないの
@date = reverse((localtime)[1..5]);
$date[0] += 1900; $date[1]++;
$now = sprintf "%4d%02d%02d%02d%02d", @date;
0246nobodyさん
02/12/06 13:27ID:???マルチは市ね
0247244
02/12/06 13:44ID:y8w9Rsa1ありがとうございました。やってみます。
0248bloom
02/12/06 13:47ID:7xw6gZYBhttp://www.agemasukudasai.com/bloom/
0249242
02/12/06 15:19ID:0nNWvuklあのコードじゃ
$aiueo = "1■2■■■3■4■5■■■6";
とかのときに最後の値を捨ててしまいますんで、
後ろにくっつけるのは区切り記号込みにしないと
だめですね。
$aiueo .= "■EOL"
@values = split(/■/, $aiueo);
pop @valures;
で、うまくいくはず。
0251nobodyさん
02/12/06 15:41ID:???@values = map($_||'NULL', $aiueo=~/(.*?)■/g);
0252nobodyさん
02/12/06 17:08ID:zqw+GwyUある文字(\x{100}以上かもしれない)が大文字か小文字か判定したいのですが、たとえば
「任意のアルファベット大文字1文字に一致するメタ表現」などはないんでしょうか。
それとも、UnicodeData.txtをいちいち読まなければならないんでしょうか。
0253nobodyさん
02/12/06 17:50ID:???改行数の多い書き込みは
「省略されました。全部読むには(略」 という感じで省略表示したいのですが
任意の改行数までを取得するにはどうすればいいでしょうか。
よろしくお願いします。
0254nobodyさん
02/12/06 18:04ID:???改行でsplitとか・・・、色々あるでしょ。
何故思いつかん?
0256nobodyさん
02/12/06 18:35ID:???0258256
02/12/06 18:40ID:???0259nobodyさん
02/12/06 18:43ID:???1だろ。
0260nobodyさん
02/12/06 18:44ID:???スマートかどうか知らんが、sortじゃだめなんですか?
sub numerically { $a <=> $b; }
@sorted = sort numerically LIST;
これで、最小値が@sortedの先頭に来ます。
0263nobodyさん
02/12/06 19:26ID:???my $a_ref = $_[ 0 ];
my $min = $a_ref->[ 0 ];
foreach (@{ $a_ref }){
$min > $_ and ($min, $_) = ($_ , $min);
}
return $min;
}
my @b= (20, 19, 100, 75, 6);
print min @b;
0264263
02/12/06 19:39ID:Wd1BEmDy@bの内容変わってる。
0265nobodyさん
02/12/06 22:56ID:???my($minimum) = sort { $a <=> $b } @list ;
print("$minimum\n");
これじゃダメ?
0267nobodyさん
02/12/07 00:15ID:???0268nobodyさん
02/12/07 00:19ID:ePZJKayyどうすればいいんでしょう?
10個あったら$hoge[9]まで、とか。
0270nobodyさん
02/12/07 00:49ID:???10要素の配列で$hoge[9]までなら全部じゃん(w
foreach (0..$#hoge-1){
print $hoge[$_];
}
とか。
0271nobodyさん
02/12/07 01:08ID:yEekv6g9http://www36.tok2.com/home/bttl/bttl-pc/
0272yani ◆saNSktNEdQ
02/12/07 01:19ID:KB9hByzAforeach (@list) {
$least ||= $_;
$_ < $least and $least = $_;
}
ベタな気がする。エレガントな解法求む。
0273yani ◆saNSktNEdQ
02/12/07 01:30ID:KB9hByzAmy $least;
foreach (@list) {
defined($least) or ($least = $_, next);
$_ < $least and $least = $_;
}
0274yani ◆saNSktNEdQ
02/12/07 02:26ID:6Rt0AxGbしかしイマイチ美しさを感じないのは気のせいか。
my($least) = @list;
foreach (@list) {
$_ < $least and $least = $_;
}
■ このスレッドは過去ログ倉庫に格納されています