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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん04/11/27 11:35:03ID:DJwiGeFM
Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0730nobodyさん05/01/13 16:29:04ID:???
>>726
print <<EOF;
1 + 2 = @{[ 1 + 2 ]}
EOF
0731nobodyさん05/01/13 16:34:24ID:???
>>730
( ゚д゚)
0732nobodyさん05/01/13 20:18:35ID:???
>>728
http://pc5.2ch.net/test/read.cgi/php/1104624784/2
0733nobodyさん05/01/13 20:24:29ID:???
>>716
Shift_JISなら分からなくも無いけど…。
Shift_JISの「ミ」も\xD0。
# またはDBの最新バージョンで人柱状態?

>>719
0xF040から0xF9FCの外字なら、予めチェックするしかないかも。

>>731
?
0734nobodyさん05/01/13 21:16:56ID:???
全文検索のスクリプトに、5件毎や10件毎表示させる機能をつけたいのですが
うまくいきません

sub search1 {
local($dir) = $_[0];
local(@filelist, $file, $filename);
opendir(DIR, $dir);
@filelist = readdir(DIR);
closedir(DIR);
$begin = $FORM{'page'} * $hyouji;
$end = $bigin + $hyouji;
if($end > @filelist) {
$end = @filelist;
}
(続く)
073573405/01/13 21:17:55ID:???
(続き)

#foreach $file (@filelist) {
for ($a = $bigin; $a < $end; ++$a) {
if ($file eq ".") { next; }
if ($file eq "..") { next; }
$filename = "$dir/$file";
if (-d $filename) {
if ($recursive_flag) {
&search1($filename);
}
} else {
&search2($filename, $dir);
}
}
if ($end < @filelist) {
$nextpage = $FORM{'page'} + 1;
print "<a href=\"$ENV{'SCRIPT_NAME'}?page=$nextpage\">次へ</a>\n";
}

#}
}
073673405/01/13 21:19:50ID:???
実行結果は1件もHITしなくなりました
動作も正常に動いてはいないようです
どなたか知恵を貸してください
よろしくお願いします
0737nobodyさん05/01/13 21:27:49ID:RpTwbNys
単純なスペルミスじゃねーのかい?
$begin
$bigin

use strict
を使う癖をつけましょう。
073873405/01/13 21:57:15ID:???
>737
ご指摘ありがとうございます
うっかりミスです

しかし直しても動作は変わりありません
構文自体が悪いのでしょうか?
頭がテンパってきました
助けてください…
0739nobodyさん05/01/13 22:01:32ID:RpTwbNys
>>738
もうちっと、ソースを整理して晒しておくれ。
search2というのが何なのかも分からないし・・・。
074073405/01/13 22:21:11ID:???
>739
すみません、インデントつけます
sub search1 {
  local($dir) = $_[0];
  local(@filelist, $file, $filename);
  opendir(DIR, $dir);
  @filelist = readdir(DIR);
  closedir(DIR);
  $begin = $FORM{'page'} * $hyouji;
  $end = $bigin + $hyouji;
  if($end > @filelist) {
    $end = @filelist;
  }

(続く)
074173405/01/13 22:23:11ID:???
    #foreach $file (@filelist) {
    for ($a = $bigin; $a < $end; ++$a) {
    if ($file eq ".") { next; }
    if ($file eq "..") { next; }
    $filename = "$dir/$file";
    if (-d $filename) {
      if ($recursive_flag) {
        &search1($filename);
      }
    } else {
    &search2($filename, $dir);
    }
  }
  if ($end < @filelist) {
  $nextpage = $FORM{'page'} + 1;
  print "<a href=\"$ENV{'SCRIPT_NAME'}?page=$nextpage\">次へ</a>\n";
  }

# }
}
074273405/01/13 22:29:34ID:???
と○ほさんのWwwsearchをもとにしています
#foreachは最初からあったやつで、コメントアウトしています
&search2はソース長いので説明すると
ループさせてファイルの中身を一文字ずつ検索させてるようです

>740の
  $begin = $FORM{'page'} * $hyouji;
  $end = $bigin + $hyouji;
  if($end > @filelist) {
    $end = @filelist;
  }
この部分と
>741の
  if ($end < @filelist) {
  $nextpage = $FORM{'page'} + 1;
  print "<a href=\"$ENV{'SCRIPT_NAME'}?page=$nextpage\">次へ</a>\n";
  }
が自分で付け足した所です
0743nobodyさん05/01/14 01:17:04ID:???
もうコーディングをいうより改造の相談だろ。
別スレでやってくれ。

★三 【 スクリプト改造工房 PART 8 】 ★三
http://pc5.2ch.net/test/read.cgi/php/1077525387/ 79にテンプレあり
0744nobodyさん05/01/14 07:32:45ID:3YybYM3/
$hoge=1.4*325;
とやると$hogeは455になるのに、
$hoge=int(1.4*325);
とやると$hogeは454になってしまいます。
他の数字でも起こるようです。何故ですか?
というか、意図した通りにさせる方法はありますでしょうか。
074572005/01/14 08:13:20ID:???
>>730
ありがとうございます。
全然誰も答えないからこのスレ、レベルが下がったのかとおもいました;
数スレ前では自分で誰かに回答してあげた覚えもあるんですが、最近の過去ログは
普通の人は見れないようで。

>>all
お前らもっと精進しろよ、な。
0746nobodyさん05/01/14 09:27:13ID:AgX5dpSc
my $a = "a*b*c*d";

異なる意味をもつ字を*で連結した上の文字列の中から1字を消して連結用のアスタリスクの数も
正常にする。

ということがしたい場合どういうみんなコーディングする?aとdでは処理が変わるんだよね。
しかしそれをなるべく簡潔にしたい。
0747nobodyさん05/01/14 09:31:58ID:???
>>744
慣れていないと面食らうがほとんどのプログラミング言語ではそれが標準仕様。
詳しい説明は「浮動小数点数」「精度」などで検索すれ。

防ぐ方法は幾つかある。まぁこのケースなら1が無難かな。

1. 整数同士の演算にする: 1.4*10*325 (1.4*325*10ではうまくいかないことに注意)
2. sprintfで処理する:sprintf '%f', 1.4*325
3. bignumプラグマ: use bignum;print int(1.4*325) (ただし破滅的なほど遅い)
0748nobodyさん05/01/14 09:32:37ID:???
>>746
何がしたいのかさっぱりわからん。
0749nobodyさん05/01/14 09:35:33ID:az2EqpkZ
$hoge1と$hoge2の2つの変数があるとします。
この2つの変数内の文字列を比較していって、先頭から同じ文字が続くところまで$hoge2から削除するにはどうすればいいでしょうか。
たとえば、$hoge1=a/b/c/d/,$hoge2=a/b/c/d/e/f/だったら、$hoge2=e/f/としたいのです。
075074605/01/14 09:37:35ID:AgX5dpSc
一応自分のコーディング(aの場合)
$a =~ s/a[*]?//;
$a =~ s/[*]*$//;
0751nobodyさん05/01/14 10:31:14ID:???
$a =~ s/^$hoge1//;
?
0752nobodyさん05/01/14 10:56:17ID:???
>>750

$a .= '*';
$a =~ s/a\*//;
chop $a;

$aを使うのはお勧めできないがそれは置いておこう。
075374905/01/14 10:58:23ID:az2EqpkZ
あ、すみません
例が適切でなかったかも知れません
$hoge1='a/b/c/d/e/f'
$hoge2='a/b/c/d/g/h/'
だったら、
$hoge2='g/h'
にしたいのです
0754nobodyさん05/01/14 11:42:26ID:LszGQepz
unixサーバ上で
「Win32::OLE」は使えないのでしょうか?
もし使えないなら、代わりになるものはありますか?
0755nobodyさん05/01/14 11:48:36ID:???
>>753
my $re = '';
foreach (reverse split //, $hoge1) {
my $q = quotemeta($_);
$re = "(?:$q$re)?";
}

$hoge2 =~ s/^$re//;
0756nobodyさん05/01/14 12:35:06ID:???
>>753

sub hoge {
  my $max = length $_[0];
  my $pos = 0;
  $pos++ while substr($_[0], $pos, 1) eq substr($_[1], $pos, 1) && $pos < $max;

  # 「$hoge2='g/h'」は typo か?
  substr $_[0], $pos, length substr +($_[2] ? $_[1] : $_[0]), $pos;
}

print hoge($hoge2, $hoge1), hoge($hoge2, $hoge1, 1); # g/h/g/h
075773405/01/14 12:52:14ID:???
>743
誘導ありがとうございます
逝ってきます
0758nobodyさん05/01/14 15:29:10ID:AgX5dpSc
携帯用のショップのCGI部分をPerlで作成中です。

現在注文管理部分の注文してくれた客に出す「確認メール」というものを作成するための
メールフォームを作っています。

docomoでは500byteまでという制限があります。
500byteなんてあっというまなので対策を考えてます。
一つ考えたのは500byteを超える場合は2通に分割するという方法です。
しかしマルチバイト文字の途中で分割すると2通目以降が悲惨なことになるので
どうにかしてそれをクリアにしたいです。

「確認メール」の内容はその時によって違うので、先に分割地点を決めるのは無理です。
メールフォームを使うのは500byteの意味を知らないパートさんで、入れ替わりなので
扱う人間に期待をするのは難しいです。

メールフォームでつくられた本文を受け取り送信する側のCGIで何とかしたいです。
日本語を綺麗に途中で分割することってできますか?簡単にできるモジュールなどありましたら
教えてください。
0759nobodyさん05/01/14 15:42:10ID:???
>>755-756
ありがとうございました。
さっそく試してみます。
076075805/01/14 15:49:19ID:AgX5dpSc
http://www.din.or.jp/~ohzaki/perl.htm#JP_Split
ここを参考にとりあえず配列に文字単位で格納して、
それから@text[0..500]などでやってみようと思います。
ただメチャクチャ重くなるような気がしてるのですが^^;

でも何かアドバイスありましたらお願いします。
0761nobodyさん05/01/14 15:51:19ID:???
>>758
Jcodeモジュールのfold使えば?
076275805/01/14 16:20:31ID:AgX5dpSc
>>761
Jcodeですか。調べてみます。
ところで
$a = 100/3;
のように$aに小数点が含まれる場合は切り上げをしたいんですがどうすればできますか?
切捨てはintで一発ですが、切り上げは一度小数点があるかないかを調べないとダメです如根。
0763nobodyさん05/01/14 16:22:41ID:???
>>762
if ( $a =~ /\./ ) {
int $a;
$a += 1;
}
0764nobodyさん05/01/14 16:30:38ID:???
整数でなければ小数。
0765nobodyさん05/01/14 16:32:42ID:???
>>762
$kiriage = ($a == int($a)? $a : int($a + 1));
0766nobodyさん05/01/14 16:52:06ID:???
>>762
POSIXモジュールのceil使う手もある。
076775805/01/14 16:59:43ID:AgX5dpSc
>>763-766
感謝ですm(_ _)m
0768nobodyさん05/01/14 19:11:08ID:???
>>762
perlメモ風の切り上げ処理は
$tmp2 = int($tmp1) + ($tmp1 <=> int($tmp1));
かな。

>>747
ありがとうございました。整数でやってみます。
0769nobodyさん05/01/15 13:17:48ID:X2SjZomE
プログラミングを頑張るのではなく、500バイトに納まるように書かせる努力をした方がいいと思うけどなぁ。
何通もメール送られたらユーザーも迷惑でしょ。
0770nobodyさん05/01/15 14:59:51ID:2P0rPuHE
Perlのテストしてたら出来なくて。
formtest.htmっていうページからformtest.cgiにデータを送信しようと
おもったんですが。formtest.htmには入力フォームが2つあってそれぞ
れdataAとdataBです。dataAはaaaとdataBにはbbbと。それをpostで送信
しました。formtest.cgiには
#!/usr/local/bin/perl

read(STDIN,$buffer,$ENV{'QUERY_STRING'});

print"Content-type: text/html\n\n";
print"<HTML><BODY>\n";
print"$buffer";
print"</BODY></HTML>\n";
とあります。画面にはdataA=aaa&dataB=bbbと表示されるはずなんですが
でません。ちなみにgetとpostの両方で送信してみましたが、出来ません、
でも他に文字を表示させるだけのCGIがあるんですが、それはは動き
ます。
0771nobodyさん05/01/15 15:11:38ID:???
>>770
根本的に間違い。
http://www.rfs.jp/sitebuilder/perl/03/02.html
ずっと下にある「GET/POST データを読み込む」でも読みたまえ。
0772nobodyさん05/01/16 10:58:07ID:LfCWlcLW
ネットショップとかで全頁をCGI(Perl)にするときに、商品数があまりなくても
すぐ2000行とかになっちゃうんですが、普通ですか?

長くなりすぎてちょっとした内容修正の時にも該当箇所までスクロールするのが面倒
だったりします。

みなさんはどうやっておられるのでしょうか?
HTML部分を別ファイルにしてメインプログラムから読み込むだけのような
形式にしてるのでしょうか?
0773nobodyさん05/01/16 11:01:18ID:???
DBでも使えば?
0774nobodyさん05/01/16 11:05:45ID:???
・ネットショップとかでページにロジックを埋め込むのは止めろよ
・コードの行数は処理次第。各ページ2000越えるのはありえない。全体で2000行のCGIでショップ運営もありえない
・めんどくさがりすぎ。行ジャンプかインク李メンタルサーチで移動
・HTMLは当然別
0775nobodyさん05/01/16 11:13:24ID:???
> ネットショップとかでページにロジックを埋め込むのは止めろよ

ページベースの設計してるPerlCgiは今はそんなにないよ。
0776nobodyさん05/01/16 12:01:04ID:???
商品数によってプログラム規模がでかくなると
思ってる時点でなんかヤバイ気がするんだが
気のせい?

もちろん大量の商品があるのでみつけやすいよう
に検索や分類の機能を作りこむとかで規模増える
ことはあるだろうけれども、そういう意味で言っ
てるようには見えない。
0777nobodyさん05/01/16 12:06:48ID:???
たしかにスクリプト中に商品データ書いてるようにしか見えない。
077877205/01/16 12:13:57ID:LfCWlcLW
>>773-776
多分みなさんレベルから見たらかなりマヌケなコーディングだと思います;
基本的に一つのindex.cgiで全頁のメインを書いてます。
現状ではHTMLもかいてます。それぞれわけるなら全面CGIにする必要性もあまり感じられませんし。

>>776
行数は増えていくと思います。商品の紹介文などを別にしない限りは。

多分みなさんが言うのはHTMLや商品コメント、価格その他はDBに突っ込んで
メインから読み込んで処理しろということだと思います。
現状は商品コメント以外はテキストファイルに作ってありますが、
なんとも中途半端な状態です。
かなりヒントになりました。あちがとうございます。

一つ質問ですm(_ _)m
使い終わった変数をundefしたいというか削除したいのですが、
undef $a;
これだとスカラー一つ筒しかできないのですがどうやればいいんですか?
my ($a,$b,$c,$d) = (undef)x4;
今はこうやってますが、これってほんとに
undef $a;
undef $b;
..
と同じ効果が得られているんでしょうか?一応中身は消えてるみたいですが。
077977205/01/16 12:19:44ID:LfCWlcLW
my ($a,$b,$c,$d) = (undef)x4;
書き間違えです。
($a,$b,$c,$d) = (undef)x4;
こっちです。
0780nobodyさん05/01/16 12:50:22ID:???
>>779
my ($a,$b,$c,$d) = (undef)x4;
foreach($a,$b,$c,$d){
printf "%sdefined", defiend $_ ?'' : 'Not';
}
0781nobodyさん05/01/16 12:57:20ID:???
>>780
アー逆スマソ。
my ($a,$b,$c,$d) = (undef) x4;
printf qq|%s -> %sdefined\r|, $_, defined $$_ ? q|Not| : q|| foreach(qw|a b c d|);
0782nobodyさん05/01/16 15:40:03ID:???
>>772
よくわからんが、HTML::Template 使うと幸せになれるとかそういう話じゃないのか

使い終った変数を undef したいというのも、なぜそんなことをしたいのかよくわからん。
巨大なメモリを喰うオブジェクトを destroy して解放したいというならわからんでもないが。
0783nobodyさん05/01/16 15:40:08ID:???
>>778
まず、明示的なundefが必要なグローバル変数を減らせ。
0784nobodyさん05/01/16 16:22:42ID:???
>>772
これはご存知?

http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlsub.html#Private_Variables_via_my_
> “my”は、それを囲んでいるブロック、条件文 (if/unless/elsif/else)、
> ループ(for/foreach/while/until/continue)、サブルーチン、eval、
> あるいはdo/require/useされたファイルに(lexicalに)閉じ込められる変数を定義します。

{
my ($a, $b, $c) = qw(1 2 3);
}
# 他で参照していない限り、ここで$a,$b,$cは無くなります。
print $a, $b, $c; # use strictならエラー

グローバル変数をundefするというのなら、
undefするより別の名前の新しい変数を作るべきです。
0785nobodyさん05/01/16 17:37:42ID:???
>>772みたいなやつが商売で使うものを作るとは恐ろしや・・・
0786nobodyさん05/01/16 17:53:52ID:???
>>784
$cはエラーになるが、
$aと$bはエラーにならないのは知ってるよね?
078778405/01/16 19:35:11ID:???
>>786
sortに使う特殊な変数ですね。

http://www.perldoc.com/perl5.8.4/pod/perlvar.html
> $a
> $b
> Special package variables when using sort(), see perlfunc/sort.
> Because of this specialness $a and $b don't need to be declared
> (using use vars, or our()) even when using the strict 'vars' pragma.
> Don't lexicalize them with my $a or my $b if you want to be able to use them
> in the sort() comparison block or function.
0788nobodyさん05/01/16 21:59:39ID:???
>>784
> グローバル変数をundefするというのなら、
> undefするより別の名前の新しい変数を作るべきです。
undefにはメモリの開放という働きもあるので、一概にはいえない。
0789nobodyさん05/01/16 22:18:34ID:???
>メモリの開放
(´,_ゝ`)プッ
0790nobodyさん05/01/16 22:48:38ID:???
>>789
チンカス君はメモリの開放という表現が嫌いかな?

↓これを
$size = 10;
$a = '0' x (1024 * 1024 * $size);
undef $a;
$b = '1' x (1024 * 1024 * $size);

undef有効にして実行
$ time perl test.pl
real 0m8.430s
user 0m1.549s
sys 0m0.334s

undefをコメントアウトして実行
$ time perl test.pl
real 0m12.044s
user 0m1.540s
sys 0m0.673s

sizeは実装メモリで加減してくれ。
0791nobodyさん05/01/16 23:26:56ID:???
use Benchmark;

$size = 1;

timethese(10000, {
'(1)' => '&test1;',
'(2)' => '&test2;',
});

sub test1 {
$a = '0' x (1024 * 1024 * $size);
undef $a;
$b = '1' x (1024 * 1024 * $size);
}

sub test2 {
$a = '0' x (1024 * 1024 * $size);
$b = '1' x (1024 * 1024 * $size);
}

Benchmark: timing 10000 iterations of (1), (2)...
(1): 272 wallclock secs (227.82 usr + 40.47 sys = 268.29 CPU) @ 37.27/s (n=10000)
(2): 251 wallclock secs (247.34 usr + 0.08 sys = 247.42 CPU) @ 40.42/s (n=10000)
0792nobodyさん05/01/16 23:31:53ID:???
ガベージコレクタの邪魔にしかなりませんね
0793nobodyさん05/01/17 01:20:52ID:???
>>791-792
馬鹿?
実装メモリの1/4位は取ってみろ。
test1は何見てんの $a確保→開放→$b確保→戻る 意味ねー
0794nobodyさん05/01/17 02:22:13ID:???
>>793
>>790そのままなんだが
0795nobodyさん05/01/17 02:34:12ID:???
>>794
undef有効の場合

>>790は各々1回しか実行しない。
$a確保→$a開放→$b確保
使用メモリ: $sizeMB

>>793は各々10000回実行する。
$a確保→$a開放→$b確保→$a確保→$a開放→$b確保→
使用メモリ: 2*$sizeMB

全然違う。
0796nobodyさん05/01/17 03:49:42ID:???
>から始まる行から>のない行まで(まだレベルが低いのでネストは対応してません)、を引用にしようと思い、

$res =~ s/(<br>>|<p>>)(.*?)<br>([^>])/<blockquote><p>>\2<\/p><\/blockquote><p>\3/g;
$res =~ s/(<br>>|<p>>)(.*?)<br>([^>])/<blockquote><p>>\2<\/p><\/blockquote><p>\3/g;
$res =~ s/>>/>>/g;
$res =~ s/([^>])<blockquote>/\1<\/p><blockquote>/g;
としてみました。

$resは書き込まれた内容をp要素で括ったものなので、
<p>>から始まる は、文頭から引用だった場合、
<br>>から始まる は、文頭ではなく、行頭から引用だった場合、です。

最後の行は、もしも、文頭ではなく、行頭だった場合、その前のp要素を閉じる、という処理です。

現状では問題は発生しませんが、
「こんな書き込み方をされたらこんな問題出るだろ」というのとかありましたらお教え下さい。

次はネストに挑戦しようと思ってるんですけど、この段階で穴がありそうな気がして前に進めません。
079778405/01/17 07:07:24ID:???
>>788
確かに変数を増やすのはメモリを使いますが、>>790のような何MBというデータは
果たして本当にグローバル変数で確保しておく必要があるのでしょうか。
メモリの1/4を使うというというのなら、設計から見直して、変数を局所化する方法を
探してみたほうが良いと思います。
0798nobodyさん05/01/17 07:55:49ID:???
>>796
想定している$resの内容がちょっとわからないけど、
$res = "<p>>引用<br></p>";
<blockquote><p>>引用</p></blockquote><p></p>
# 続くP要素内がカラになる

$res = "<p>>引用</p>";
<p>>引用</p>
# 引用できない
079977205/01/17 08:55:35ID:???
みなさんありがとうございます。
作成中はuse strictしてるので、局所化はしています。
undefしたいのは気持ち的な問題で、コードを自分で読むときに
この変数は用無しというのをハッキリさせたいだけです。
あほらしいと思いますが、ブロック内でのローカル変数も
たまにundefしています。メモリ云々は考えていません。
080077205/01/17 09:03:45ID:???
>>781

my ($a,$b,$c,$d) = qw/1 2 3 4/;
print $a,$b,$c,$d,"<br>";
($a,$b,$c,$d) = (undef) x4;
printf qq|%s -> %sdefined\r|, $_, defined $$_ ? q|Not| : q|| foreach(qw|a b c d|);

全部definedになりました。しかし3行目(undef行)をコメントアウトしても結果は同じでした。
どういうことでしょうか?

print defined $a;
でやると結果は変わりました。ちゃんとundefが聞いてるようです。
0801nobodyさん05/01/17 09:28:20ID:???
>>798
引用の次に文章が来ないと、引用にならない、って問題ですね。
なるほど。甘かったです。
0802nobodyさん05/01/17 10:46:32ID:1F0SQQP0
my @a = qw/1 2 3 4 5 6 7......99/;

この配列の中から0以上50未満の一番大きい数値を値として持っている
のは何番目かを簡単に調べることはできますか?

sort関数はなにやらややこしいので、いまいち理解できていませんが、
やはりsort関数を使わないと難しいでしょうか?
0803nobodyさん05/01/17 10:57:01ID:???
>>802
降順ソートをかましてforeach内ifの条件を50未満にすれば一発。
080480205/01/17 11:52:05ID:1F0SQQP0
>>803
ありがとうござまい。とりあえず作ってみました。
1つのサイズの上限を決めて改行分割の最大限サイズで分割するものです

一応動くのですが他に思いつかないので無限ループをしています。
$limitがいくつであってもループから抜けれるようにはしてありますが、
できれば無限ループは怖いし、共用サーバでは他人に迷惑をかける可能性があrますので
避けたいです。
無限ループを使わずにこれと同じような処理をすることは不可能でしょうか?
080580205/01/17 11:55:51ID:1F0SQQP0
my $ascii = '[\x00-\x7F]';
my $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
my $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
my $p = "あいうえお\nかきくけこ\nさしすせそ\n";
my @mail = $p =~ /$ascii|$twoBytes|$threeBytes/og;
my @return;
my $i = 0;
foreach (@mail){
if ( $_ =~ /\n/ ) {push @return,$i}
$i ++;
}
@return = sort { $b <=> $a}@return;
my @text;
my $befor = 0;
my $limit = my $limit2 = 4;
while ( 1 ) {
my $limit3 = $limit;
foreach ( @return ){
if ( $_ >= $befor and $_ <= $limit ) {
push @text,join '',@mail[$befor..$_];
$befor = $_;
$limit += $_;
}
}
last if $limit > $#mail + $limit2 || $limit == $limit3;
}
foreach (@text) {print $_ ,"<br><br>"}
0806nobodyさん05/01/17 12:30:59ID:???
>>802

$n = (sort {$a[$b]<=>$a[$a]} grep { $a[$_] >= 0 && $a[$_] < 50 } 0..$#a)[0];

あるいはList::Utilのreduce使って

$n = reduce {$a[$b]>$a[$a]? $b: $a} grep { $a[$_] >= 0 && $a[$_] < 50 } 0..$#a;

reduceはO(n)だからO(n×log n)のsortより要素数が多ければ速くなるだろうと
期待できますが、要素数少なければsortの方が速いかも。
0807nobodyさん05/01/17 16:41:34ID:wVIIMywn
POSTで送られてきた内容に対して
値を返したいのですがどうすればいいでしょうか?
0808nobodyさん05/01/17 17:14:50ID:???
1: 入力されたユーザー名のユーザーを作りたい
2: System("su
        passwd
        useradd $username その他のオプションも
        exit");

これじゃ無理だと思いながらやたンですけどヤパリ無理でした
0809nobodyさん05/01/17 17:21:37ID:???
>>808
sudoつかえば? 注意して設定しないと穴になるけど。


0810nobodyさん05/01/17 17:38:11ID:???
>>807
意味不明
0811nobodyさん05/01/17 21:05:30ID:fcKelFvp
配列の中に特定の要素が一つでもあればOKと言うような
コードを書くのにforを使って書けば済むのですがgrep等を使ってもっと
簡潔に書きたいと思っています。
しかしgrepは恐らく配列全部参照するので配列数が多くなるにつれて
処理が遅くなってしまうのではないかと思い、以下のようなものを書いてみました。

@test = (1..999999);
$Atime = time;
for($i=0;$i < @test;$i++){
if($test[$i] eq "1"){
print"ひっと\n";
last;
}
}
$rest = time - $Atime;
print"time:$rest\n";
$Atime = time;
print"ひっと\n" if grep ("1" eq $_,@test);
$rest = time - $Atime;
print"time:$rest\n";
sleep(9999);

やはり、forに比べてlastしない分grepのほうが遅くなりました。
grepのように簡潔にかけてforと同じもしくはそれ以上の速度が出せるような
コーディングの仕方はないものでしょうか・・
アドバイスお願いします。
0812nobodyさん05/01/17 21:39:56ID:???
>>811
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq4.html#How_can_I_tell_whether_an_list_o
081381105/01/17 22:07:21ID:???
>>812
大変貴重なページを教えていただきありがとうございます。
How can I tell whether an list or array contains a certain element?
あたりに載ってますね。それ以外にも勉強すべき内容が沢山あって本当に助かりました。
0814nobodyさん05/01/18 01:27:26ID:5YMtxRb8

CIGでアクセスログの取得を考えています。
ログ取得に関する部分は下記の通りです。

if(open(FL,">> $file")){
print LOG "時間\tIP\tHPST\tなど…\n";
close(FL);
chmod 0666,$file;
}

ログの解析や表示に時間がかかるのは問題ないのですが、
保存には負荷がかからないようにと考えています。
追加書込モードなら負荷や破損を押さえられると思うのですが、
20万〜30万行程度の蓄積となると負荷は相当違ってくるものなのでしょうか?
081581405/01/18 01:29:10ID:5YMtxRb8
>>814に関して訂正

ログ取得に関する部分は下記の通りです。

if(open(FL,">> $file")){
print FL "時間\tIP\tHPST\tなど…\n";
close(FL);
chmod 0666,$file;
}
0816nobodyさん05/01/18 01:43:47ID:Oto1zFxV
SSIが使えないので、Perlスクリプトをimgタグで呼び出すように作ったんですが、
IEで見た場合、画像が無い時のxが表示されてしまいます。
これをうまいこと出さないで、imgタグでスクリプトを呼び出す事は出来るでしょうか?
0817nobodyさん05/01/18 01:46:02ID:???
>>816
1*1ドットの透過画像でも表示させましょう。
0818nobodyさん05/01/18 02:46:19ID:sIFYihq9
会員約500人分のデータ(URLやサイトの紹介)をWeb上管理したいですが、
このぐらいの数を管理するのに良い方法ってありますか?
使っているサーバはPHPは使えません。

今まで修正・削除などを
「ファイル開く→全データ取り込む→該当データを検索→処理→処理結果を反映して保存」
この単純な方法でやってきたんですが、もっと良い管理方法がありますか?
0819nobodyさん05/01/18 02:57:58ID:???
>>814-815>>816>>818
スレ違い
0820nobodyさん05/01/18 03:43:06ID:mDYssaxT
フォームメールを改造しています。

print <<END_OF_MESSAGE;
…
$ { PrintMessage() }
…
END_OF_MESSAGE

sub PrintMessage {
#ここにある配列を加工したものを上に出すにはどうしたらいいでしょう?
}
0821nobodyさん05/01/18 03:52:41ID:???
>>820
その関数PrintMessageではデータの加工ぐらいしか行わない方が良い。
${}を使ってヒアドキュメント内で出力させるようにするにはprintを使わないと行けない上に、
出力した物は${}があるところではなくヒアドキュメント内の一番最初に出力される。
だから、一回ヒアドキュメントやめるか、配列とか変数に入れといてヒアドキュメント内で出力した方が吉。
0822nobodyさん05/01/18 04:05:21ID:???
>>819
どうした?構って欲しいのか?
0823nobodyさん05/01/18 04:22:12ID:mDYssaxT
>>821
> 出力した物は${}があるところではなくヒアドキュメント内の一番最初に出力される。

げげっ、それは知りませんでした。書き直します。
ありがとうございました。
0824nobodyさん05/01/18 08:32:39ID:???
>>821
副作用じゃなくて文字列返す関数にして、スカラー式を
文字列リテラルに埋め込む慣用句の${\(式)}使えばいい。

print <<END_OF_MESSAGE;
…
$ { \PrintMessage() }
…
END_OF_MESSAGE

sub PrintMessage {
my $s = "適当な文字列";
return \$s;
}
0825nobodyさん05/01/18 10:17:22ID:aExMxO8W
my $a = "aeo,huor,tuuu,gfd";
my $b = "aio,r,3s2r,waaaas,tuuu,huor";

$bの中から$aにないものを削除したいんですが、どうすればいいでしょうか?
$aにあるものを削除するのはわかるので、$aにあるものを$bから新しく$cに移す
という方法は思いついたのですが、なんかいけてないんですよねorz

もっとかっこいいやりかたできませんか?
人間の脳みたいに、違うものという判断をしたら該当部を削除するといった処理を。
0826nobodyさん05/01/18 12:15:23ID:???
>>825
こんなんでどうでしょう?
#--------------------------------------------
my $a = "aeo,huor,tuuu,gfd";
my $b = "aio,r,3s2r,waaaas,tuuu,huor";
$a = ',' . $a . ',';
$b =
join ('',
map { (index ($a, ',' . $_ . ',') < 0) ? '' : $_ . ',' }
split (/,/, $b) );
chop $b;
#--------------------------------------------
082782605/01/18 12:17:02ID:???
↑ map と split の前に タブスペース お願いします。(見やすく)


私も質問なんですが、
ライブラリとかモジュールは、 @INC の中から勝手にファイル検索して読み込んでくれるんですが、
「そのライブラリの中の階層にあるテキストファイル」
を同じように*簡単に*読み込む方法ってありますでしょうか?

例えば、
--------------------------------------------
lib/
 |- Hoge.pm
 |- Hoge/
   |- Hoge1.txt
   |- Hoge2.txt
honya.cgi
--------------------------------------------
があるとして、
--------------------------------------------
# honya.cgi
unshift (@INC, qw(lib ../lib) );
--------------------------------------------
--------------------------------------------
# Hoge.pm
my $dir = ''; # ←ここに勝手にファイルのあるフォルダを検索していれたい
open (TXT, $dir.'/Hoge1.txt');
--------------------------------------------
foreach (@INC) 〜 でやればなんとかできるんですが、
もっと上手い方法でできるなら教えてください。
調べてもわからなかったのです。
そういうことを書いてあるページとかあったらそれでもいいですので。
0828nobodyさん05/01/18 12:22:27ID:???
>>820
sub PrintMessage{
my $message;
# ...
return \$message;
}
print <<EOT;
${ PrintMessage() }
EOT

>>821
ごく一般的なイディオムだと思うが?

>>824
知識が半端過ぎますから!残念!
0829nobodyさん05/01/18 12:33:26ID:???
>>828
関数の戻り値は文字列にして${}の中でリファレンスとる方が
オレは好きだな。

sub PrintMessage{
my $message;
# ...
return $message;
}
print <<EOT;
${ \PrintMessage() }
EOT

083082005/01/18 13:25:04ID:fG6Vu+xI
その後、下のようにしたのですが、配列(文字列配列)の2番目以降の先頭にスペースが
入ってしまいます。

print <<END_OF_MESSAGE;
…
@hairetu
…
END_OF_MESSAGE

配列の中身を出すには、↑のようなやり方はまずいんでしょうか?
■ このスレッドは過去ログ倉庫に格納されています