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

Perl コーディング初心者質問コーナー Part33

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん04/03/01 02:46ID:1GeWO7LH
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0611nobodyさん04/03/19 01:11ID:???
>>610
- が0個or1個
0612nobodyさん04/03/19 01:36ID:???
>>610
正規表現の一つ。
0613nobodyさん04/03/19 03:57ID:KxdLBMtC
>>611
サンクス
0614nobodyさん04/03/19 08:52ID:???
すぐ♪そこ♪
0615nobodyさん04/03/19 13:29ID:3UeG122v
DBに保存する掲示板の、書き込みを検索する機能を作っています。

検索結果を表示するときに、Googleみたく検索キーワードを強調表示し、
さらにその前後の文字列を含めて切り抜いているのを実装したいのですが、
どのようにすればよいでしょうか。

たとえば、
「私はりんごが好きで、あなたはみかんが好きで、二人はバナナが好きです」
を「りんご バナナ」で検索した際、検索結果には
「私は<em>りんご</em>が好きで、あ...で、二人は<em>バナナ</em>が好きです」
という感じにしたいです。前後五文字を切り抜いています。

これだけならなんとかなりそうですが、「あなた みかん」で検索したときに
「...が好きで、<em>あなた</em>は<em>みかん</em>が好きで、二...」というように
切り抜き範囲に別なキーワードがさらに見つかった場合などを考えるといい方法が浮かびません。
061661504/03/19 13:36ID:???
すみません大事なことを書き忘れました。
検索して見つかった文章は$textに入っていて、検索キーワードは@keywordsに配列で入っています。

foreach $keyword(@keywords){
  $text =~ s/(.*)($keyword)(.*)/substr($1,-10)<em>$2<\/em>substr($1,10)/eg;
}
こんな感じのを考えていましたが、いろんな場合を考えるとイマイチなのは先ほど書いたとおりです。
0617nobodyさん04/03/19 14:32ID:???
>>615-616
ここはコーディングスレ。

>「...が好きで、<em>あなた</em>は<em>みかん</em>が好きで、二...」
これの何がイヤなのか知らんが、どうしたいか仕様ぐらい考えてから来い。
061861504/03/19 15:37ID:???
>>617
すいません、イヤなんじゃなく、むしろそうしたいんです・・・。

基本的には、前5文字. <em>キーワード</em>. 後5文字 で切り抜く。
ひとつの文章内で複数ヒットしたら、切り抜きを「...」で結ぶ。
複数ヒットしたキーワードが切り抜き幅以内の近距離にあった場合は
まとめて前後5文字で切り抜く

さらに、文頭や文末だったら「...」はつけないとかいう気配りも欲しいです。

自分で作ったのは
$preview = $text;
foreach $keyword(@keywords){
  $preview =~ s/($keyword)/<em>$1<\/em>/g;
}
$preview =~ s/([^>]*)(<em>.*?<\/em>)([^<]*)/"...". substr($1, -30). $2. substr($3, 0, 30). "..."/eg;

それっぽいだけで、これではあちこち不備があるようです。
文章内で複数ヒットしたときにキーワードより前が切り抜かれなかったりしてます。
0619nobodyさん04/03/19 16:16ID:???
直感だが、正規表現置換には向かんのではないかなあ。

「アルゴリズム+データ構造=プログラミング」という古い格言に従って、
コードを書く前にまずどういうアルゴリズムで実現するか考えてみるべきだろう。

一例だが、以下のようなアルゴリズムが考えられる。

1. ヒットした文字列の部分にマークをつける
2. その前後5文字にもマークをつける
3. 非マーク部分を削除しつつ、マーク/非マークの境界に "..." を挿入

これをコードに落とすときはどうするかと言うと、
配列をマーク用に用意し、文字と配列要素を1対1に対応させて、
キーワードの出現位置を index で検出し、その前後の配列要素を1にして、
全部検出終わったら、次は配列を前から舐めてって1のところと0のところを…
みたいな感じ。
062061504/03/19 17:14ID:???
>>619 ありがとです。なんとかコード起こしてみました。
行数制限に引っかかるので省略記法で書いてます。
あとは半角文字が含まれた場合の対応と、この強引なコーディングをもう少しスマートにしたいです。
ポイントをご教授いただければ幸いです。

$preview = ''; $pos = 0; $flg = 0; # 変数初期化
$mark[$_] = 0 for(0..length($text)); # マーク初期化
# マーク付け
foreach $keyword(@keywords){
  while(1){
    $markPos = index($text, $keyword, $pos); # キーワード出現位置取得
    if(0 <= $markPos){
      $mark[$_] = 1 for(($markPos - 10)..($markPos + length($keyword) - 1 + 10));
      $pos = $markPos + 1;
    }else{
      last;
    }
  }
}
# マーク判別して $preview 生成
for(0..length($text)){
  if(($flg == 0) && ($mark[$_] == 1)){ $flg = 1; }
  if(($flg == 1) && ($mark[$_] == 0)){ $flg = 2; }
  if(($flg == 2) && ($mark[$_] == 1)){ $flg = 0; $preview .= "...";}
  $preview .= substr($text, $_, 1) if($mark[$_]);
}
# キーワードの強調
foreach $keyword(@keywords){
  $preview =~ s/($keyword)/<em>$1<\/em>/g;
}
0621nobodyさん04/03/19 17:16ID:???
今は試せないので正規表現は省略するが、
キーワードに<em></em>を付けた後、
</em>(もしくは文頭)〜<em>(もしくは文末)の〜が11文字以上あった場合間を...に置換、
ではどうだろうか?
062261504/03/19 17:40ID:???
>>621
書いてみたら意外に難しかったです。
しかも正しく動いてないっぽい・・・。
</em>(5文字) .* (5文字)<em> のところがうまくいったりいかなかったり
( ... にならずそのまま出る)です。

$preview = $text;

# キーワードの強調
foreach $keyword(@keywords){
  $preview =~ s/($keyword)/<em>$1<\/em>/g;
}

if($preview =~ /^(.+?)<em>/){
  if(10 < length($1)){
    $preview =~ s/^.+?(.{10})(<em>)(.*)$/\.\.\.$1$2$3/;
  }
}
if($preview =~ /<\/em>(.+?)$/){
  if(10 < length($1)){
    $preview =~ s/^(.*)(<\/em>)(.{10}).+$/$1$2$3\.\.\./;
  }
}
if($preview =~ /<\/em>(.+?)<em>/){
  if(20 < length($1)){
    $preview =~ s/(<\/em>.{10}).*?(.{10}<em>)/$1\.\.\.$2/;
  }
}
0623nobodyさん04/03/19 19:34ID:???
$writer = "n";
$diary{"order"} = "nm";

$diary{"order"} =~ s/$writer//e;

この様なスクリプトを書きました。
ローカルで実行すると
$diary{"order"} = "m";
と意図した動作をしたのですが,サーバにアップするとこのような動作をしません。

これは何でなのでしょうか
062462304/03/19 19:37ID:???
ちなみにサーバでは
$diary{"order"} = "mmn";
となります
0625nobodyさん04/03/19 19:58ID:???
>>623
なぜeオプション?
062662104/03/19 22:20ID:???
>615
$previewに特定の文字(以下では\0)が含まれていない事が条件だが、
こんな感じでどうだろう?

foreach $keyword(@keywords){
$preview =~ s/($keyword)/<\0>$1<\/\0>/g;
}
$preview =~ s/(<\/\0>[^\0]{10}|^)[^\0]+?([^\0]{10}<\0>|$)/$1\.\.\.$2/g;
$preview =~ s/\0/em/g;
062762304/03/19 23:28ID:???
あっ!
多分これが原因ですね…
ありがとうございました
0628nobodyさん04/03/20 10:10ID:pZHNeEFd
BBSのPerlの投稿表示の部分を修正していて、
メールアドレスがある場合はNAMEにリンクさせて、ない場合はリンクが発生しないということをしたいのですが…

if (($MAIL ne "") && ($NAME ne "")) { print "<b>:<a href=mailto:$MAIL>$NAME</a>:</b>\n";
}elsif (($MAIL ne "") && ($NAME eq "")) { print "<b>:<a href=mailto:$MAIL>nobodyさん</a>:</b>\n";
}elsif (($MAIL eq "") && ($NAME ne "")) { print "<b>:$NAME:</b>\n";
}elsif (($MAIL eq "") && ($NAME eq "")) { print "<b>:nobodyさん:</b>\n";
}

↑では上手くいきません。
MAILを入力しようとしまいとmailto:でリンクされます。
NAMEはしっかり分岐して動いてます。
どのように修正したらいいんでしょうか?
0629nobodyさん04/03/20 10:25ID:???
>628
$MAILの中身が本当に空っぽかどうかをしっかり確認するべき。
あと、こうした方が見やすいぞ。

if($NAME eq ""){$NAME = "nobodyさん";}
if ($MAIL ne "" ) { print "<b>:<a href=mailto:$MAIL>$NAME</a>:</b>\n"; }
else { print "<b>:$NAME:</b>\n"; }
0630nobodyさん04/03/20 13:11ID:???
>>628
if ($MAIL eq "") { ... を if ($MAIL) { ... にしても一緒かなぁ。
0631nobodyさん04/03/20 13:18ID:???
>>630
それだとメル欄に1とか0とかで入れられるとマズいのでは、
0632nobodyさん04/03/20 13:19ID:Y1bzghLT
ほんとうに初歩的な質問で申し訳ないのですが
配列と配列をつなぎ合わせるにはどうしたらよいでしょうか?
@array1 = (1,2,3);
@array2 = (4,5,6);
例えばこの配列の操作に関してなのですが
@array1 = (1,2,3,4,5,6);
と言う様にしたいのです。pushを使えば@array1 = (1,2,3,[4,5,6]);
となってしまいますし、foreach (@array2) { push (@array1,$_)}のように
すればいいと思うのですが、同様に操作したい配列が後に@array3 @array4...
と続いているのでもう少しスマートな方法でしたいと思っております。
joinか何かでできたような気がするのですが方法を見つけることができませんでした。
よろしければアドバイス頂けないでしょうか?
0633nobodyさん04/03/20 13:34ID:???
>>628
print "Content-type: text/html\n\n";print <<"EOF";
<HTML><HEAD><TITLE></TITLE></HEAD><BODY>
EOF

# データ入れて試して。
$MAIL = "";$NAME = "";

if ($MAIL ne "") {
if ($NAME ne "") {
print "<b>:<a href=mailto:$MAIL>$NAME</a>:</b>\n";
} else {
print "<b>:<a href=mailto:$MAIL>nobodyさん</a>:</b>\n";
}
} else {
if ($NAME ne "") {
print "<b>:$NAME:</b>\n";
} else {
print "<b>:nobodyさん:</b>\n";
}
}
print <<"EOF";
</BODY></HTML>
EOF

これなら動いたが。全部をelsifにするのはイクナイ。MAILが空の場合と値がある場合でifはわかりやすく2つ置こう。
0634nobodyさん04/03/20 13:35ID:???
>MAILが空の場合と値がある場合でifはわかりやすく2つ置こう。
これ消し忘れ。スマソ。
0635nobodyさん04/03/20 13:38ID:???
>>632
@array1 = (@array1, @array2);
これじゃマズいの?
0636nobodyさん04/03/20 13:55ID:???
>>635
・・・だぁぁぁ 俺寝不足なのかな。
ありがとうございました。頭のトロイ子丸出しで申し訳ないです。
0637nobodyさん04/03/20 18:17ID:???
>>632

>pushを使えば@array1 = (1,2,3,[4,5,6]);

……そんなんなるかなあ。
リファレンス見たら、第二引数は配列でいいことになってるぞ。

push @array1, @array2;
他にもあるんなら、
push @array1, ( @array2, @array3, @array4 ... );
でいいんじゃねえか。

push @array1, [@array2];
とか、
push @array1, \@array2;
とか変なことやってんじゃねえのか?

もしくは、@array2自体におかしな代入しているとか。
0638nobodyさん04/03/20 20:29ID:bXEf4bM+
strict な perl で、ハッシュのキーから変数を生成したいんですが、
以下のようなスクリプトだと、何も print してくれません。
--------------------------------
use strict;
my %hash = (
name1 => 'hoge',
name2 => 'fuga'
);
for my $key ( keys %hash ) {
$main::{$key} = $hash{$key};
}
print $main::name1;
exit;
--------------------------------
更にできれば $main::name1 ではなく $name1 で取得したいんですが、
perl 5.6 以下なんで our も使えません。(perl 5 です)
どうすればいいのでしょうか???
0639nobodyさん04/03/20 21:05ID:???
意味が分からん。
>$main::{$key} = $hash{$key};
>print $main::name1;

なにをやってるのかよく考えて見れ。
>更にできれば $main::name1 ではなく $name1 で取得したいんですが、
これもめっちゃイミフ。
064063904/03/20 21:07ID:???
ところで、
>何も print してくれません。
俺のperlではちゃんとエラーメッセージをprintしてくれたけど。

Name "main::name1" used only once: possible typo at - line 9.
Use of uninitialized value in print at - line 9.

064163804/03/20 21:11ID:bXEf4bM+
>>639

すんません。。。
分かりにくかったですね。 m(_ _)m
------------------
my %hash = (
name1 => 'hoge',
name2 => 'fuga'
);
------------------
というハッシュから、
------------------
my $name1 = 'hoge';
my $name2 = 'fuga';
------------------
という変数定義をしたいって意味です。

use strict なしでは、
------------------
for my $key ( keys %hash ) {
${$key} = $hash{$key};
}
print $name1;
------------------
とやると、ちゃんと 'hoge' が print されてたんですが、
use strict した場合に同じことをする方法が思い当たらなかったので。。。
0642nobodyさん04/03/20 21:12ID:???
>>638
シンボリックリファレンス。
strictな記述ではスカラー変数の自動生成出来ない。
あと、ourがサポートされてるperlでもシンボリックに対してourは認識されない(と思った記憶)
0643nobodyさん04/03/20 21:15ID:???
ハッシュのキーと同一な名前をもつ変数をpackage mainのネームスペースにインポートしたいという事だろうが、
そんな設計が駄目設計だという事に気付け。
064463904/03/20 21:18ID:???
>use strict した場合に同じことをする方法が思い当たらなかったので。。。
strictした時はおそらく自動生成出来ないと思われ。
no strictすれば?
あと、俺もあまりそれ良い設計とは思えない。
064563804/03/20 21:21ID:???
>>642
変数の自動生成が出来ないとは知りませんでした。。
ご指摘有難うございます。

>>643
ダメ設計かどうかもわからなかったです。。(初心者丸出しだ…
もっと勉強します。

変数の動的生成は個人的に結構使いそうだと思っていたんですが、
普通にperl自体では避けた方がいいのでしょうか???
0646nobodyさん04/03/20 21:22ID:???
>>638
http://www.perldoc.com/perl5.005_03/lib/strict.html

ループ括弧内で、no strict "refs";使うしか。

どんな変数を展開するか知らないけど、
外部から入力された値をmainパッケージで展開するとなると、
セキュリティホールになるかも。
(PHPのregister_globals問題と同じ。)
064763804/03/20 21:25ID:???
>>644
CGIで、フォームからのクエリを %form に入れて、
%form のキーから変数を自動生成しようと思ってました。

素直に
my $name1 = $form{name1};

とするしかないですよね。。(汗
0648nobodyさん04/03/20 21:26ID:???
>変数の動的生成は個人的に結構使いそうだと思っていたんですが、
>普通にperl自体では避けた方がいいのでしょうか???
普通は同じ事が出来て、見やすくて、記述が綺麗になって、速度も速い方法が他に用意されてるから。
それと、ハッシュのまま使うのが一番柔軟で使いやすくもある。スカラーにしたい理由が見つからない。
064963804/03/20 21:31ID:???
>>648

スカラーにしたかった理由は、>>647 です。
同じことが出来て、速い方法…
すいません。教えていただけますでしょうか…
0650nobodyさん04/03/20 21:33ID:???
>>649
647のどこにスカラーにしたい理由が書いてありますか?
065164804/03/20 21:36ID:???
>>649
長い変数名書きたくないって理由だったらお断りだよ。
ただ、キミがちゃんとことごとく局所化する記述書けてるなら、

sub age{
  my $age = $form{'age'}; #この関数ではこの値を使う。
  #処理
}

みたいな記述はお勧めできる
0652nobodyさん04/03/20 21:40ID:???
>>650

フォームからのクエリを %form に取得した後に、
スカラー変数を自動生成して、
スクリプトの記述量($form{})を減らしたかったのが主な理由です。
065363804/03/20 21:43ID:???
>>651

(゚Д゚)…まさにその理由でした。。。
あんま楽すんなってことですね…

みなさん失礼しました。
065464804/03/20 21:44ID:???
>スクリプトの記述量($form{})を減らしたかったのが主な理由です。
減らさんくて良し。
スカラーにしたら汚くなる&処理の柔軟さを捨てるだけだから。

どーしても自動生成したいなら、>>646のヤツ使うよろし。
誉められた記述じゃないけど、自動生成の中ではそれが一番マシ。
065563804/03/20 21:46ID:???
>>651

今までは
my $name1 = $form{name1};
my $name2 = $form{name2};
…
と記述していたところを、
もっと簡単に定義できないかというのが今回の発端でした。

651さん、、親切に有難うございました。。。
0656nobodyさん04/03/20 21:52ID:???
んじゃ変数名を$fとか$nみたいに短くすれば?
後で見たとき間違いなく意味不明になるが。
0657nobodyさん04/03/20 22:02ID:???
>>656

それはそれで混乱しますね…
地道に書くのが一番ですか。。。がんばりますw
0658未承諾広告※ ◆TWARamEjuA 04/03/20 23:34ID:???
れすくーとかの影響なのだろうか・・・(哀)
0659nobodyさん04/03/21 00:40ID:???
>>658
おまい以外誰も影響受けてないから安心汁
0660nobodyさん04/03/21 02:34ID:???

$type eq 'A' or $type eq 'B' or $type eq 'C' or $type eq 'D';

上記の記述なんですが、もうちょい短くならないでしょうか?
$typeと4回書かれているのはなんか俺の感性に反するんですが…。
それだけの理由です。
0661nobodyさん04/03/21 02:39ID:???
>俺の感性に反するんですが…。
感性よりも知識を付けろハゲ
066266004/03/21 02:52ID:???
すんません、やりかた思いつきました。

scalar grep {$type eq $_} (A, B, C, D);
コスト高いけどこれで(・∀・)
0663nobodyさん04/03/21 02:55ID:???
$type =~ /^[A-D]$/
066466004/03/21 02:58ID:???
グハッ! 正規表現の存在忘れてた。。。
ありが�d。
066562804/03/21 11:31ID:???
>633
動きますた(=゚ω゚)ノ
他の方々も貴重な情報さんくすこでした(*´Д`)ハァハァ
0666nobodyさん04/03/21 11:36ID:???
>>660
何度もチェックする、チェック対象が複雑、などの場合はハッシュを使ってチェックするのが最速。

my %valid_types = map{ $_ => 1 } qw(A B C D foo bar baz);

if($valid_types{ $type }){
# ...
}
0667nobodyさん04/03/21 15:06ID:???
perlって読みにくいね。
C#の方がいいじゃん。
0668nobodyさん04/03/21 15:44ID:???
>>667
C#しかできないだけだろ(プゲラ
0669nobodyさん04/03/21 18:13ID:???
>>667
どこを指して読みにくいのかと。
Perlは読みにくいといいたいだけちゃうんかと。
0670nobodyさん04/03/21 19:39ID:Bb+Pz/Rr
PerlのCGIでファイルの文字コードをUTF-8にして保存、サーバ上で実行するとエラー500になります。
簡単なCGI(例えばHello World等)でテストを行いましたが、エラーの解決法がよくわかりません。
UTF-8(Unicode)以外の文字コードにするとプログラムは正常に動きます。
PerlではUTF-8は一応サポートされていて実際使っている方もいるようですが、
何かうまくいくコツなどありましたらどうかご指南ください。
0671nobodyさん04/03/21 19:49ID:???
>>670
エラーログ等でPerlのエラーを確認すること。
0672nobodyさん04/03/21 20:08ID:???
あれだろ。
「ぱーる」って読むのか「ぴーる」って読むのかわかりにくいってんだろ。
「しーしゃーぷ」は見たまんまだもんな。
0673T.K04/03/21 20:55ID:???
>>655

$key に name1 が、 $valに中身があるとして

クエリを分解して読み込むときに

${$key} = $val;

ってやってforeachでループさせれば君のやりたいことはできるよ。
実は俺も長くなるからそうやってたんだけど
やっぱあとあと大変だということがわかった。
PHPに乗り換えようとしたときも変数の取り扱いがちょっと違うだけで
違和感感じてなじめなかった。

おとなしく$form{}でやってたほうがよいよ。
0674nobodyさん04/03/21 20:56ID:???
そうか?
しーどんぶり、じゃねえの?
0675nobodyさん04/03/21 21:10ID:???
perl は ぱるる、
url は うるる、
ってのは、もはや常識ですね
0676T.K04/03/21 22:36ID:???
ぺーる
0677T.K04/03/21 22:38ID:???
>>675

じゃあNullPointerExceptionは?
0678nobodyさん04/03/21 22:46ID:???
なるぽ
0679T.K04/03/21 22:57ID:???
           _∧_∧
        / ̄ ( ・∀・)⌒\ 待ちくたびれたぞ
   __    /  _|     |   |
   ヽヽ   /  /  \    |   |           ,,,,,,,iiiiillllll!!!!!!!lllllliiiii,,,,,,,
    \\|  |____|   .|   |           .,llll゙゙゙゙゙        ゙゙゙゙゙lllll,
     \/  \       |   |           .|!!!!,,,,,,,,       ,,,,,,,,,!!!!|
     | ヽ_「\      |   |、         |  ゙゙゙゙!!!!llllliiiiiiiiiilllll!!!!゙゙゙゙ .|
     |    \ \――、. |   | ヽ         .|     .゙゙゙゙゙゙゙゙゙゙     |
     |   / \ "-、,  `|  |  ヽ       |               |
  _/   /    "-, "' (_  ヽ  ヽ      .|               |
/    __ノ      "'m__`\ヽ_,,,, ヽ      |               |
`ー― ̄          ヽ、__`/ー_,,,, ゙゙゙゙!!!!!!!lllllllliii|               |
                    \゙゙゙゙゙゙゙!!!!!lllllllliiiii|               |
                      \   ヽ   |               |
                       ヽ   \  |               |
                        |     \.|               |
                        `ヽ、,,_ノ|               |
                              ゙゙!!!,,,,,,,,       ,,,,,,,,,!!!゙゙
                                   ゙゙゙゙!!!!llllliiiiiiiiiilllll!!!!゙゙゙゙
                                /.// ・l|∵ ヽ\
0680nobodyさん04/03/22 02:26ID:???
数字が22531などの切りのイイ数字でない場合、端数を切って22000と言うような
ことをしたいので無い知恵絞って以下のような事を考えてみたのですが
これだと予想していないような桁には対応できませんしやり方が不細工かなと思いまして。
いつもは動けばいいが信条なのですがもう少しスマートに書けないか悩んでいます。
数字桁数を操作する関数などがあればいいのですが。お知恵を拝借できないでしょうか?

if ($price <= 999){
$tempPrice = (int($price / 10)) * 10;
}elsif($price > 999 && $price <= 9999){
$tempPrice = (int($price / 100)) * 100;
}
0681nobodyさん04/03/22 02:32ID:???
有効数字2桁ってことか?
068268004/03/22 02:42ID:???
>>681
はい。
1桁2桁など可変できれば更にうれしいですが今は先頭2桁固定にできれば幸せになれます。
0683nobodyさん04/03/22 03:28ID:???
@n = qw/1 11 111 1111 11111 111111/;
$d = 2;
foreach (@n) {
s/(?<=.{$d}).+/'0' x length $&/eg;
print "$_\n";
}
0684nobodyさん04/03/22 03:29ID:???
m/^([0-9]{2})([0-9])*/;
$1 . ('0' x length $2);

今すごく適当に思いついて作っただけ。
0685nobodyさん04/03/22 06:57ID:???
my $position = 2;
my $mask = 10**(length($price)-$position);
$price = int($price/$mask)*$mask if ($mask > 0);
0686nobodyさん04/03/22 08:04ID:???
substr($num, 0, 2, '0' x length($num)-2);
0687nobodyさん04/03/22 08:06ID:???
>>686
あ、間違えた。
0688nobodyさん04/03/22 08:43ID:???
my @num = qw/1 11 111 1111 11111 111111/;
my $digit = 2;
foreach my $price (@num) {
my $len = length $price;
$price -= $price % (10 ** ($len - $digit)) if $digit < $len;
print "$price\n";
}

>>685
if に頼らずコンピュータの演算誤差なんかで丸めることって出来ませんかね?
0689nobodyさん04/03/22 09:48ID:UDEoFMoy
#! /usr/bin/perl

use Jcode;

$a="abc";
Jcode::tr(\$a, '0-9A-Za-z', '0-9A-Za-z');

print "Content-Type: text/html\n\n";
print $a;


上記CGIスクリプトが、
E200042 "Not an ARRAY reference at C:/Perl/site/lib/Jcode.pm line 439."
というエラーになってしまいます。なにがいけないのでしょうか。
perl 5.6、Jcode.pmは0.82 です。

このスクリプトは、半角文字を全角にするためのテストで書いたもので、
実際には$a内の全ての半角を全角にしたいです(記号・カタカナ等も)。
そういった処理を一発でできる関数ってのは無いですよね?
069068504/03/22 10:41ID:???
>>688
$maskは0にならないから、if文要りませんでした。
(%演算子では0で剰余を取ろうとして、上手くいきませんね。
if文を消すなら、三項演算子でごまかすという手もありますが、小手先技ですね…)

my $position = 2;
my $mask = 10**(length($price)-$position);
$price = int($price/$mask)*$mask;

>>689
# スクリプトがEUC-JPで書かれているとして
$a = Jcode->new('abc')->tr('0-9A-Za-z', $replacement);
0691nobodyさん04/03/22 10:43ID:???
>>690
> $a = Jcode->new('abc')->tr('0-9A-Za-z', $replacement);
$a = Jcode->new('abc')->tr('0-9A-Za-z', '0-9A-Za-z');
でした。
069268904/03/22 11:36ID:???
sub getWide{
  # 半角を全角に(英字はさらに大文字に)変換
  $jcode = Jcode->new(\$_[0]);
  $jcode->tr('0-9A-Za-z', '0-9A-Za-z');
  $jcode->tr('a-z', 'A-Z');
  $jcode->tr(' !#$%&()=^~\|@`[{;+:*]},<.>/?_-', ' !#$%&()=^ ̄¥|@‘[{;+:*]},<.>/?_−');
  $jcode->h2z->euc;
}

>>690を参考にして、関数にしてみました。
オブジェクト指向な書き方をしないとだめなんですね。

これですべて全角になるでしょうか?記号を変換しているところは思いつく記号('と"以外)を
やみくもに列挙しただけで、足りないものがあるかも知れず不安です。
ハイフンは最後にかかなきゃいけないのに気づくのに苦労しました(今後のためのメモ)

また、最後の一行で半角カナを全角にしてるんですが、
「ダ」は「タ゛」になっちゃいますか?と思って実験したら、
ちゃんと「ダ」になりました(今後のためのメモ)。
069368004/03/22 12:24ID:fR/XRXq7
>>688
>>685
なるほど!こういうやり方もあるんですね。悩んでいただけに目からウロコと言うか。
ありがとうございました。スマートだなぁ。
0694nobodyさん04/03/23 01:49ID:???
>>688
負の時ダサい。
0695nobodyさん04/03/23 05:07ID:???
win環境しかなく、鯖を使ってテストは迷惑だろうと思い質問させていただきます。
open (OUT,">$num.dat");
print OUT $buffer;
close (OUT);
として新規ファイル名$num.datに$bufferの内容を書き込むとき、
パーミッションはいくつになってるのでしょうか?
また、こういう風なことをするとき、みなさんex1のようにchmodで変更してると思うのですが、
ex2のようにopenした直後にchmodで変更ってことは出来ないのでしょうか?
(ex1のようにしたくない理由がちょっとありまして・・・。)

#------------------------------ex1
open (OUT,">$num.dat");
print OUT $buffer;
close (OUT);
chmod 0606,"$num.dat";
#------------------------------
#------------------------------ex2
open (OUT,">$num.dat");
chmod 0606,OUT; # これは無理なら chmod 0606,"$num.dat";
print OUT $buffer;
close (OUT);
#------------------------------

ディレクトリなら確か作るときに第二引数でmodeを渡せたと思うのですが、
ファイルは出来ないようでちょっと困ってます。
0696nobodyさん04/03/23 05:14ID:???
>>695
http://perldoc.com/perl5.8.0/pod/func/sysopen.html
0697nobodyさん04/03/23 05:22ID:???
>>696
前に調べてたときにsysopen知ったんですが
使わないほうがいいみたいなこと書かれてましたけど大丈夫なんでしょうか?
0698nobodyさん04/03/23 06:15ID:???
>>965
FileHandleモジュールか、IO::Fileモジュールでパーミッションの指定ができます。
0699nobodyさん04/03/23 06:22ID:???
>>697
バッファリングするヤツと一緒に使ってはいけない。
umaskとかはどうですか?
0700nobodyさん04/03/23 08:31ID:???
>>694 そう思ったら貴様が作れよ。。なんちて

my @num = qw/1 -1 11 -11 111 1111 11111 111111 -111111/;
my $digit = 2;
foreach my $price (@num) {
my $len = length(my $p_price = abs $price);
$p_price -= $p_price % 10 ** ($len - $digit) if $digit < $len;
$price = $p_price * ($price <=> 0);
print "$price\n";
}
0701nobodyさん04/03/23 14:54ID:???
04とか03とか2桁に整形された形の数字から
0をとり省くのはどのような方法があるでしょうか?
0702nobodyさん04/03/23 14:54ID:awaWqGNM
use strict;

sub hogehoge{
my @myarray;

(中略)

$myarray[5][0] = 'foo';
$myarray[5][1] = 'bar';
$myarray[5][2] = 'hoge'
・
・
・
}

と同じようなことをpushを使ってやりたいのですが、
どうすればいいのでしょう?

試しに
push ($myarray[5] , 'foo');
のようにやると、
「Type of arg 1 to push must be array (not array element) at」
と怒られてしまいます。
0703nobodyさん04/03/23 14:57ID:???
>>701

my $num = '03';
$num = sprintf( "%d", $num );
0704nobodyさん04/03/23 15:00ID:???
>>703 さん
なるほど。有難うございます。

>>702
push (@{$myarray[5]} , 'foo');
0705nobodyさん04/03/23 15:00ID:???
>>702
push @{$myarray[5]}, qw(foo bar hoge);

リファレンスわかってて、なんでデリファレンスわからんかなあ
0706nobodyさん04/03/23 15:01ID:???
>>702

よく意味がわからんけど、
pushの二つ目の引数は配列じゃなきゃだめ
070770604/03/23 15:03ID:???
誤爆。
一つ目の引数
0708nobodyさん04/03/23 15:17ID:???
>>701
整形された数字 *= 1;
0709nobodyさん04/03/23 16:22ID:???
HTML::Templateモジュールでは、
最後に print $template->output;で
ブラウザに表示するのが普通ですが、
これを、HTML全体を変数に格納する方法はないでしょうか?
071070904/03/23 16:39ID:???
自己レス

my $foo = $template->output;
でOKですた。。。
■ このスレッドは過去ログ倉庫に格納されています