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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/06/26(月) 00:46:38ID:???
Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0133nobodyさん2006/07/02(日) 18:53:53ID:???
129だが解決方法を教えてくれ
0134nobodyさん2006/07/02(日) 18:58:30ID:???
せめて sub error を晒せ。
いまんとこ解決というかそれは当たり前というか。
>>130 も書いている通りなんだが。
>>131 もなんか書いてるし。
それを参考にどうぞ。
0135nobodyさん2006/07/02(日) 19:00:42ID:???
>>131
配列の添え字は整数しかとらないんだし、
randの引数はスカラーコンテキストだからこれで良いじゃないか。
sub error { print $_[rand @_] }

>>132
何をしようとしているときに問題が発生するのかが良くわからんので、問題が発生するときの
・内部エンコーディング(UTF-8ならutf-8フラグはあるのかどうかも出来れば)
・出力/入力するエンコーディング
・どっちの方向に変換しようとしているのか
辺りを詳しく。

スクリプトの内部処理をUTF-8で行って、出力するページのエンコーディングを
EUC-JPにしようとしているわけ?勘では多分、使い方の間違いだ。
Jcode::convert(\$value, '変換先のエンコーディング', '元の文字列のエンコーディング');
ってやって見れ
01361322006/07/02(日) 19:09:39ID:n0vd3nFA
>>135
ごめんなさい、誤解させてしまうような書き方をしてしまいました

基本的には内部においてUTF-8で処理したいのです
eucやsjisに変換する気はありません

ただどんな文字コードでフォームから入力されても
UTF-8に変換したいために
Jcode::convert (\$value, 'utf8');
としています

# 現在のブラウザではフォーム入力ページがUTF-8なら
# UTF-8で文字コードを送信してくれるという話なので(どっかで聞きました)
# Jcode::convert (\$value, 'utf8');
# をしなくても実害はないといえば実害がないのですが
# 万が一sjisとかで送信してくるブラウザ等があった場合にも
# 対応したいと思い変換処理させています

ところでUTF-8フラグはEncodeモジュール以外でも必要なのでしょうか?
(今回の件で色々ぐぐっていたときUTF-8フラグというものについても読んだのですが
Jcodeモジュールを使う時にフラグ云々という話は出てこなかったので不要なのかと思っていました)

続きます
0137nobodyさん2006/07/02(日) 19:10:50ID:???
Jcode::convert (\$value, 'utf8');
を
jcode($value)->utf8();
にしてみたら?
自動判別が働いて正しく格納されるはず。

入力のエンコードを誤認してたらどうしようもないけどね
0138nobodyさん2006/07/02(日) 19:11:56ID:n0vd3nFA
入力された文字列を処理させる流れは以下のような感じです

sub decode {
my ($buffer, $key, $value);

if ($ENV{'REQUEST_METHOD'} eq "POST") {
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
$buffer = $ENV{'QUERY_STRING'};
}

@pairs = split(/&/, $buffer);
foreach (@pairs) {
($name, $value) = split(/=/);

$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

Jcode::convert (\$value, 'utf8');

$in{$name} = $value;
}
}
0139nobodyさん2006/07/02(日) 19:16:54ID:???
あの〜packしてる時点でスクリプトを書いている文字コードへ変換しているはずですが・・・

># 万が一sjisとかで送信してくるブラウザ等があった場合にも
># 対応したいと思い変換処理させています
そりゃおまいさんがどんなコンテンツを管理しているかによる。
UTF8で書かれたページからshiftjisで
しかもフォームデータをエンコードもせずにダイレクトで送ってくるブラウザ
使ってる奴なんて死ねばいいと思うよ
0140nobodyさん2006/07/02(日) 19:19:08ID:???
139の一行目はなんか激しい勘違いなので忘れてw
0141nobodyさん2006/07/02(日) 19:23:43ID:n0vd3nFA
>>137
jcode($value)->utf8();
にしてみたら上手く行ったかと思ったのですが
ためしにフォームページをEUC-JPにして入力してみると
入力された文字列はEUC-JPのまま出力されていました・・・

>>139
>しかもフォームデータをエンコードもせずにダイレクトで送ってくるブラウザ
>使ってる奴なんて死ねばいいと思うよ

もうちょっと正直に書きますと
ある分野のデータベースを作っているのですがその検索フォームを
「自分のサイトにつけたい人はどうぞ」
という風にしたいと考えているのです
ですのでその入力ページがeucもあればsjisもあるかと思うので
鯖側でUTF-8に変換したいなあと・・・

最後まで解決しなければその案は断念しますがw
0142nobodyさん2006/07/02(日) 19:47:20ID:???
>>138
切り分けができてないな。そんなに長いプログラムではどこで
間違ってるか特定できないだろ。

Jcode::convertを疑うのなら、4valueにこの値をいれて
Jcode::convertを呼んだらこれこれこうなったけど
期待している値はこれだというのを示さないと。
0143nobodyさん2006/07/02(日) 20:06:33ID:n0vd3nFA
>>142
えっと・・・このソースの大半は一般的な入力データ処理だと思いますが・・・
とりあえず>>132で書いた通り
Jcode::convert (\$value, 'utf8');
をコメントアウトすれば問題なく処理されます

一応文字化けした結果も載せておくと
「心霊」をUTF-8で記載されたページから入力すると
unpackされた値は「%E5%BF%83%E9%9C%8A」になりそれをpackして
Jcode::convert (\$value, 'utf8');
で変換すると「綽??」(← 文字化けしたもの)
となってしまうというわけです(当然期待している値は「心霊」です)

ちなみに「心」だけでも「霊」だけでも正常に出力されます
0144nobodyさん2006/07/02(日) 20:40:15ID:???
いやだから??とか文字化けしたとかじゃわかんないでしょ。
utf8フラグと文字コードのダンプぐらい示さないと。
0145nobodyさん2006/07/02(日) 20:48:13ID:???
ためしに
Jcode::convert (\$value, 'utf8', 'euc');
と
Jcode::convert (\$value, 'utf8', 'sjis');
ってやった結果も記してくれんかな
0146nobodyさん2006/07/02(日) 20:55:32ID:???
そもそも他人に使わせるなら日本語限定ではだめじゃん?
ttp://www.russky.net/article/list.asp?id=855
これは gb2312 だけど euc-kr にも日本語のひらがなが入っていたようないないような。
0147nobodyさん2006/07/02(日) 21:13:47ID:???
おおかたencode/decodeを適切にやってないと予想。

0148nobodyさん2006/07/02(日) 21:35:08ID:???
ああ、大体わかった
「綽??」ってのはUTF-8の文字列をEUC-JPとして見たときのものだ。

つまり変換自体には問題はなくて、結果を表示するページを
間違えてUTF-8じゃなくEUC-JPにしてしまっている、と。
0149nobodyさん2006/07/02(日) 21:47:43ID:pDw8h7zX
s/\x0D\x0A/\n/g;
tr/\x0D\x0A/\n\n/;
とかって、改行コードの統一処理はどのタイミングでやるもの?
何かファイルを読み込むごとに毎回するもの?
0150nobodyさん2006/07/02(日) 21:52:43ID:???
混在してるとごちゃごちゃするので、なるべく入り口近くで決めた形式に
統一しちゃうね。場合によっては無駄になることもあるけどわかりやさ
優先。
01511322006/07/02(日) 22:03:39ID:n0vd3nFA
>>144
>>143の??は実際には文字化けの□をもっと縦長にした感じのが出ています
ただここにコピペしたら?に変換されてしまったわけで

>>145
入力ページはUTF-8で記載されていますのでその上での結果です
>Jcode::convert (\$value, 'utf8', 'euc');
「綽??」
>Jcode::convert (\$value, 'utf8', 'sjis');
「蠢?怺」
ちなみに↑の例ですが入力ページをそれぞれeucおよびsjisに変えたら問題ありませんでした
今回の「心霊」のようにそれぞれの文字コードで別の問題ある文字がないとは限りませんが・・・

>>146
そうかもしれません

>>147
その可能性がないとは言えませんが私は適切にやってるつもりなのでなんとも

>>148
ブラウザでのエンコードはUTF-8になっていることを確認した上で見ています
なのでブラウザの問題ではなくむしろ下に書くように
jcode.pmモジュールがUTF-8をEUC-JPに誤読しているのかと・・・

つづく
01521322006/07/02(日) 22:04:39ID:n0vd3nFA
今回試しに下のような形でエンコードしたところ
Jcode::convert (\$value, "utf8", "utf8");
正しく「心霊」と表示されました

また「心」と「霊」は単独で正確に表示できることから
思うに「心霊」と続けて入力したとき
繋がっている部分の文字列から文字コードをEUC-JPと判断された上で
UTF-8に変換しているのではないかと個人的には思っています

例) #文字コードについて調べるのが面倒なので下記のような仮定で・・・
UTF-8 : 心→aaaaaa 霊→bbaabb
EUC-JP : 綽→aaaa ?→aabb ?→aabb


今めちゃくちゃ眠いので
もしかしたら落ちてしまって反応明日以降になっちゃうかも・・・
そのときはごめんなさい

あと、忘れていたのですが、ご回答頂いた方々、ありがとうございます
0153nobodyさん2006/07/02(日) 22:07:24ID:???
>>150
それは、
「コードの最初の方に1箇所だけ統一処理を置いて読み込む度に処理される」
ということを意味してるのか、
「必要不要は置いといて、オープンする度に毎回とりあえず統一処理する」
ということなのか、どっちの意味ですか?
読解力不足ですみません。
01541482006/07/02(日) 22:27:28ID:???
>>151-152
そうか、ごめん。こっちの環境ではちゃんと自動認識できてたもので、つい。

なら、SJISの一バイトカナの問題もあるし、
呼び出し元のフォームでエンコーディングを指定してもらうか、
もしくはフォームに適当なマルチバイト文字列を埋め込んでおいて、
それが何になったかでエンコーディングを調べるってのはどうよ。

# formにはaccept-charsetなんてのもあるのだけれど、IE対応してないんじゃ仕方ない…
01551322006/07/02(日) 22:38:32ID:n0vd3nFA
>>154
ご回答くださり有難うございます
なるほど、その方法がありましたね
ソース見られるとちょっと不恰好だけど・・・

てゆーか素朴な疑問なのですが
jcodeモジュールを使っている人で同じような問題に当たった人って居ないのかなあ・・・
eucで「〜」を入れるとNGというのは発見したのですが

# ちなみに入力ページをEUC-JPにした上で「〜」を入力したところ確かにNGでした

自分一人だとしたら、やっぱり何か私の書き方がおかしいんだろうな・・・
jcode.plではこんなこと一回もなかったのでjcode.pmが嫌いになりそう
0156nobodyさん2006/07/02(日) 22:45:18ID:???
ってか受け取った文字列が utf-8 かどうかなんて自分で1行書いて判別すれば起こらない問題じゃね?
0157nobodyさん2006/07/02(日) 22:49:46ID:???
143の%エンコードっされた文字列をみるに
Jcode::convertには

"\xe5\xbf\x83\xe9\x9c\x8a"

という「心霊」をutf8にしたバイト列を食わしているわけだが、
$Jcode::DEBUG=3にしてこいつを変換すると

>DEBUG:sjis = 6, euc = 2, utf8 = 6 at 〜

と出るので、sjisとutf8のスコアが同点でどっちにも決められない
状態になっていることがわかる。

これは避けられないことなので、普通はhiddenで判定用文字列を
渡してどういうのが来るかで文字コードを決定し、他のパラメタに
ついてはJcodeの自動判定にたよらずその文字コードを入力コード
に指定してやるのが安全。
01581322006/07/02(日) 23:19:43ID:???
ご回答頂きありがとうございます

>>156-157
なるほど、了解しました
とくに>>157さんは細かく調べて頂き深く感謝致します

>>154さんも仰っていたように
判定用文字列を渡してチェックする方向で対処したいと思います

長い時間お付き合い頂き、皆様、本当にありがとうございました
0159nobodyさん2006/07/02(日) 23:58:34ID:???
正直、convertサブルーチンを使う気ならjcode.pl使えばいいじゃん。
Jcode.pmはオブジェクト指向が前提だし、その先にはEncodeへの視野がある。

使いこなせないなら無理すんな
0160nobodyさん2006/07/03(月) 01:25:18ID:???
>159
jcode.plはUTF-8に対応して無いんだが
0161nobodyさん2006/07/03(月) 01:44:49ID:???
>153
答えた本人じゃないけど・・・
>「必要不要は置いといて、オープンする度に毎回とりあえず統一処理する」
だと思う

俺も基本的にはデータファイルを読み込むときに改行を統一 (または不要なら削除) してる

「あれ? このデータは改行付だったっけか?」 なんて迷うことも少なくなるので、
自分でどの段階でまとめておくとか、自分なりのルールを決めておくといいかと思います。
0162nobodyさん2006/07/03(月) 02:25:22ID:???
早く文字コードが統一される時代が来ないかな
もうこのさいUTF-8でもSJISでもなんでもいいからさ
0163nobodyさん2006/07/03(月) 07:23:23ID:???
>>157
utf8の心霊はそんなにもeucっぽいという事?w
でも、実際には文字化けしてるわけで、・・・なんか変な感じだ・・・
0164nobodyさん2006/07/03(月) 07:27:52ID:???
>>129
$_[0]=="ダメだ"
$_[1]=="ダメっす"
自分の経験からするとこういうランダムは、すぐにうっとうしくなるw
0165nobodyさん2006/07/03(月) 09:14:35ID:???
>>162
unicodeはいい機会だったのだが日本語については従来のコード
との対応について統一に失敗したのでだめぽ。まったく当時その
辺で仕事してた奴らは負の遺産を残してくれたものだ。

01661492006/07/03(月) 10:05:01ID:???
>>161
もう誰もレスくれないと思ってたからちょっと感動。

やっぱり、オープンの度にコード統一する癖付けといた方が何かと良さそうですね。
これで改行統一の野望に一歩近づきました。
ありがとうございます!
0167nobodyさん2006/07/03(月) 12:27:50ID:???
sjisで統一されたら面倒くさくて超困るしw
utf8は神。もうちょっとがんばってはほしかったが。

jcode の文字自動判別は前からいろいろ問題あったよね。
length で判定して同じ文字数だったらEUCにするので、
sjis で半角カナだけ書いて文字判別させると文字化けするとかね。
優先順位指定できたらもっと使いやすかったと思う。
0168nobodyさん2006/07/03(月) 12:30:55ID:???
孫がトロン潰しさえしなければなぁ・・・
0169nobodyさん2006/07/03(月) 14:44:46ID:???
>>167
>jcode の文字自動判別は前からいろいろ問題あったよね。
よくしらないので教えて欲しいんだけど、
utf8で文字化けしないencode方法あるの?
googleとかで文字化けしたの見たことないし方法あるのかなあ。
0170nobodyさん2006/07/03(月) 18:36:40ID:???
>>169 > utf8で文字化けしないencode方法あるの?
ごめん、日本語でおk

(フラグのない) utf8 だって見分けるのは簡単でしょ。
最初の文字から最後の文字まで ascii と utf8 だけだったら utf8 てすればいい。
ああいう特徴的な文字の並びはほぼ間違いなく utf8 なんだから。

掲示板とかで sjis で HTML 書いてて、ほとんどそのフォームからデータ送信して受け取るのに、
euc と sjis が候補にあがった場合、わざわざ euc だと推測するのはおかしいでしょ?
その推測を頼りに決定しまってるのが jcode の convert というか getcode の欠点。
半角カナの文字化けだって、sjis 判定に半角カナのコード範囲を入れてないから起こるもの。

だから、何でもかんでも 1行で変換を済まそうとせず、
一旦 Encode::Guess の guess_encoding みたいに推測して文字コードの候補をとり、
複数の候補があった場合、プログラマがどっちを優先して変換するか書いて決めればいいんじゃないかと思うわけ。

長ぇ!
0171nobodyさん2006/07/03(月) 19:43:50ID:???
つーか、普通にパラメータ増やして、文字コード
送信すれば?
<input type="hidden" name="encoding" value="sjis">
バイナリから推測なんてメンドクサイ、ムズカシイ、確実じゃない、いい事何もない。
0172nobodyさん2006/07/03(月) 19:47:02ID:???
たしか質問者は、そのプログラムを他の人のページから使わせる気なんでしょ?
利用者が文字コード知ってて、しかもフォーム書き換えてくれるなんて
あまり期待できないと思うけど。
0173nobodyさん2006/07/03(月) 20:01:53ID:???
検索とかで、ブラウザのアドレスから
http://〜/~.cgi?q=ほげほげ
ってやったときの文字コードなんて何になるかわかんないしな
0174nobodyさん2006/07/03(月) 20:41:54ID:DxhEPLl+
「ファイルの中身の任意の1行だけを書き換える」という処理をする方法なんですが、
open(FH,$FILE);
while(<FH>){
if(マッチ条件){処理}
push(@newdata,$_);
}
とすると、マッチして書き換えた後もファイルの中身を最後まで読み込んで無駄な処理が出てしまいます。
lastとかで飛ばしたいところですが、そうするとファイルの中身が書き換えた行以降消えることになります。
こういうとき、どういう処理をすれば無駄なく完遂できるんでしょうか?
セオリーみたいなものがあれば教えて下さい。
0175nobodyさん2006/07/03(月) 20:50:54ID:???
>>172
自分のページにフォーム作ろうなんて考える利用者はHTMLぐらいかけるでしょ普通
で、文字コード別にフォームのソース置いといて、化けない奴使ってね、て書けばたぶん分かる。
何にも知らない人はそもそも変なフォームから送信してこないので問題ないと思う・・・

>>173
フォームから入力したいって言ってるんだからGETメソッドに対応しなければいいのでは?
どうしてもGETも対応したいって場合も、ばけたら&en=***なんとかを付けて見て下さいみたいな
誘導でなんとかなりそう・・・
そもそも、アドレス欄からクエリー送信してくるのは上級者だと思う
0176nobodyさん2006/07/03(月) 20:51:54ID:???
>>174
読み込みで開いてるので消えない
0177nobodyさん2006/07/03(月) 21:08:28ID:???
ブラウザに送ってくる文字コードを指定する方法があって、すべてのブラウザが
それを守ってくれればいいのだが、とんでもないのが存在するのも現実だ。

一番ひどいと思ったのはhiddenとそれ以外で別のコードで送ってきやがった
某ブラウザ。数年前の話だから今は改善されてるかな。
0178nobodyさん2006/07/03(月) 21:11:39ID:???
>>174
176の指摘はおいとくとしても、偶然同じ長さの行に書きかえるのでない限り
それ以後の内容を前後にずらす必要があるので、そういうことは考えるだけ
無駄ですな。

File::Inplaceの使用をお勧めする。
0179nobodyさん2006/07/03(月) 21:14:39ID:???
>>174
一気に read でファイルの中身全部読み込んじゃって、
あとは s{^(マッチ条件).*}{ 処理 }em; とかして、
一気に書き出せばいいんじゃね?
01801742006/07/03(月) 22:04:52ID:DxhEPLl+
>>176
いや、確かにファイルの中身自体は消えてませんが、そういうことでは…。

>>178
多少の無駄には目をつぶって最後まで走らせておくのが吉なんですかね。
File::Inplaceについては調べてみます。ありがとうございました。

>>179
確かに正規表現で1回マッチ直後に処理すれば、無駄はなくなる…けど、
処理そのものの負担が大きくなってしまうような…。


色んな場面で必要にかられる処理だと思ったので、
他の人はどんな風に処理してるのか適当にCGIを見てみたところ
>>174に書いてあるのが結構多かったかも。
中には
open(FH,$FILE);
my @data = <FH>;
my $loop = @data;
my $i;
while($loop>0){
@temp = split(/ /,$data[$i]);
if(マッチ条件){
処理
last;
}
$i++;
$loop--;
}
ってのも、ありました。ちょっとゴテゴテしてるなぁ。
0181nobodyさん2006/07/03(月) 22:05:46ID:???
KENTを見て育ってる者だ。
よくlocal何て使わないでmyと書いてあるがすべてmyにしたらダメだよね?
ちょっと違いが分からないので教えて欲しい・・・。
0182nobodyさん2006/07/03(月) 22:14:19ID:???
>>180
> 処理そのものの負担が大きくなってしまうような

何でそう思うのかkwsk

my @data = <FH>;
↑こんなことしてる方がよっぽど負担強いてると思うぞw

>>181
コーチ変えたほうがいい。
0183nobodyさん2006/07/03(月) 22:19:42ID:???
>>182
KENTが一番楽だったからそれにしてたいが今更コーチ変えろって
簡単で見やすいスクリプトなんてあるの?
何せKENTのスクリプトをみて覚えてきた人間だから今更となると見やすいスクリプトじゃないの無理な気がする。
0184nobodyさん2006/07/03(月) 22:20:53ID:???
>>183
じゃあそのままでいろよ。
0185nobodyさん2006/07/03(月) 22:24:31ID:???
っていうかKENTが神、ってネタか釣りなんだろ?そうなんだろ?
0186nobodyさん2006/07/03(月) 22:48:13ID:???
KENTがperl5で全部書き直すか、プログラムの配布を止めれば
状況は変わると思う。
0187nobodyさん2006/07/03(月) 22:54:50ID:???
>>174
任意の一行ってことはマッチする行がはじめから一行しかない
事が分かってるってことですかね?
それともマッチした最初の行だけとか、?(それだと174はまずいですよね・・・
ファイルの構造が固定してるなら、該当する行をダイレクトに指定
できる可能性とかはありえない・・・?
0188nobodyさん2006/07/03(月) 23:07:15ID:???
KENTはKENT未満の読むに値しない汚いスクリプトから初心者を守ってるから神。
0189nobodyさん2006/07/03(月) 23:16:27ID:???
つか、皆から見てKENTのソースってどうなん?
初心者のオイラにはなんのこっちゃか分からない行がたくさんあって、ちょっと嫌
0190nobodyさん2006/07/03(月) 23:20:54ID:???
つい最近前スレだかでも話題になったからパス。
セキュリティくらい考えて作れよー。

まあKENT儲は ∩( ´∀`)∩コチラヘ (っ´∀`)っ))ドウゾ

KENT WEB 総合スレ Part2
http://pc8.2ch.net/test/read.cgi/php/1078991985/
0191nobodyさん2006/07/03(月) 23:32:34ID:???
>>181
…向上心があるなら、出来るだけ早い内にPerl5流に馴染んでおいたほうが楽だぞ。本当に…
きっと、各種モジュールに興味が出てきた頃に、矯正するのに時間がかかって苦労する。というか、した。
# 独学だと何がまともなのか、判るようになるまでが難しい

閑話休題。多くの場合では、myに置き換えて大丈夫だと思う。
localとmyの違いは効果の範囲が動的…プログラムの流れに沿ったものか、
静的…ソース上のブロックに対応したスコープか、と言うのが一番の差。
以下、差を顕著にするためのどうしようもない汚い例。
sub fuga { $foo }
sub hoge_my { my $foo = 'hoge'; print 'my: ', fuga(), "\n" }
sub hoge_local { local $foo = 'hoge'; print 'local: ', fuga(), "\n" }
$foo = 'outer'; hoge_local(); hoge_my();
---------------
local: hoge
my: outer

あと型グロブのように、単純にmyに置き換えることの出来ないものもあるけれど、
これも、出来る限りリファレンスを使って書くのがPerl5流。
localの出番はPerlで定義済みの変数($/の類)とか。

何か大事な点がすっぽ抜けてたら、フォロー宜しくお願いします。
0192nobodyさん2006/07/03(月) 23:36:24ID:???
local は変数宣言ではないので、use strictすると
local しただけではエラーになるので注意。my か our などが必要。
0193nobodyさん2006/07/03(月) 23:37:39ID:???
>>191 は親切すぎるぜ…
01941742006/07/03(月) 23:46:28ID:DxhEPLl+
>>182
>何でそう思うのか
いや、単純に感覚的なものなので間違ってたらすみません。
ファイルの中身が数千行とかあった場合で、
該当する行の情報もそこそこ大きい場合、
全部読み込んで正規表現にかけるより
1行ずつチェックした方が良さそうに思っちゃいました。

>>187
>任意の一行ってことはマッチする行がはじめから一行しかない
>事が分かってるってことですかね?
その通りです。でも、その行はどこにあるのかは分からないし流動的。
掲示板とかアクセスログとかのログと同じようなもんですね。
なので、ダイレクトに指定することはできないです。
0195nobodyさん2006/07/04(火) 00:01:32ID:???
>>194
数千行ならさあ、
数千回ループさせて、数千回ファイルからデータとってきて、数千回 @array にその大きいデータを push するのと、
改行の数なんか関係なく 1回 read して $scalar に入れて 1回だけ置換 するのと、
総合的にどっちが良さそうに見える?

まあその数千行のファイルが ウン十Mb とかなら話は変わるけど、そんな規模のデータファイル作ったりはしないよね。
とりあえずいくつか方法で迷ったらベンチでもとっとけばいいと思う。
0196nobodyさん2006/07/04(火) 07:41:17ID:???
DB使ったほうが楽だと思うけどね。途中だけ書き換えるとか
かなり不毛。ファイルを編集するのが目的ならしょうがない
かもしれないが、データ保存用ならいくらでもやりようがある
はずだ。
0197nobodyさん2006/07/04(火) 10:28:25ID:???
こういう話題だとDB使えって人はクライアントの仕事したことないんかね?
0198nobodyさん2006/07/04(火) 12:30:08ID:???
ファイルが大きくなるなら、複数のファイルに分けて、インデックスも作っておく。
掲示板のログと一緒。
0199nobodyさん2006/07/04(火) 12:47:20ID:???
$titleに入っている題名の間隔を空けて表示したいのです
置換でなかなかうまく行きませんでした
良い方法はありますか?
0200nobodyさん2006/07/04(火) 13:02:03ID:???
エスパー頼む
0201nobodyさん2006/07/04(火) 13:11:56ID:???
$title =~ s/([\x80-\xff].|[\x20-\x7e])/$1 /g;
0202nobodyさん2006/07/04(火) 13:27:20ID:???
>>199
css使いなさいな
0203nobodyさん2006/07/04(火) 14:42:27ID:???
>>201
ありがとうございます

CSSの本も2冊買っているのですがじっくり取り組む時間がなくて
これもやってみます
0204nobodyさん2006/07/04(火) 22:40:59ID:???
>>174
もう、納得すみかも知らんが

#!/usr/bin/env perl -w
my @data = ();
my $flag = 0 ;
while ( <> ){
if( /print/ ){ s/print/say/ ; $flag ++ }
push @data, $_ ;
last if $flag != 0 ;
}
push @data, <> ;
print @data ;

これを hoge.pl として保存して
% perl hoge.pl hoge.pl
してみそ?
0205nobodyさん2006/07/04(火) 23:22:36ID:???
foreach $loopsubject(@datname){
foreach(@localsubject){
if($_=~/$loopsubject/){
$localsubjectmatchswitch=1;
last;
}else{
$localsubjectmatchswitch=0;
}
}
}
のようなスクリプトを書いたのですがif($_=~/$loopsubject/)で判定してくれません。
判定後の処理にprint "match";を書いてみると何も帰ってきません。
@datnameの内容は
1152013113.dat
1152013147.dat
のようなものです。@localsubjectには2chのsubject.txtのような内容が入っています。
@loaclsubejctの中に@datnameの中身が入っているか判定したいのです。
入っていたらスイッチを1にしてループを終了させて、ループが全部終わったときに
スイッチが0だったら書き込みの処理をしたいです。

なぜ判定してくれないのでしょうか?教えてください。お願いします。
0206nobodyさん2006/07/04(火) 23:32:02ID:???
2行目に
chomp $loopsubject ;
入れてみるとか…。
02072052006/07/04(火) 23:57:29ID:???
>>206
ありがとうございます!検出はうまくいきました!
でも今度はすでに@localsubjectにあるはずなのに無いと検出されます…なんででしょうか?いろいろ試してみたけどわかりません。
スイッチの検出は
if($localsubjectmatchswitch==0){
$writesubject=$datname[$i]."<>".$threadtitle[$i];
unshift(@localsubject,$writesubject);
}
のようにしてやってます。
0208nobodyさん2006/07/05(水) 00:06:26ID:???
まさか last で外側の foreach ループまで一緒に抜けるとは思ってないよね・・・?
内側の foreach ループのあとに、フラグに関する処理が入ってるんだよね・・・?
0209nobodyさん2006/07/05(水) 00:07:58ID:???
お前さん
>>205 では
$localsubjectmatchswitch=1;
ってマッチしたとき 1 代入してんのに
>>207
では 0 のときの処理を書いてるよ。
0210nobodyさん2006/07/05(水) 00:12:06ID:???
>>205,207 が何やってるか全然わからないのは俺の頭が悪いだけかな?
0211nobodyさん2006/07/05(水) 00:16:10ID:???
変数名が長い
0212nobodyさん2006/07/05(水) 00:29:19ID:???
>>208,209
内側のforeachループでローカルsubject.txtの中身を調べて
マッチしたら1を返してすべてにマッチしてなかったら処理をするようにしています。0の時の処理を書いてるのはそのためです。
外側のforeachループは検索語を順番に処理するようにしてあります。
で、どうしたらいいんでしょうか?理論的には問題が無いように見えるのですが…
なぜマッチしたはずなのにマッチして無いとみなされるんでしょうか?
>>211
変数名長くしないとわからないアホな子なんです。許してやってください。
02132052006/07/05(水) 00:31:21ID:???
>>212は>>205です。名前欄入れ忘れました。すいませんでした。
>>208
>内側の foreach ループのあとに、フラグに関する処理が入ってるんだよね・・・?
そのとおりです。
0214nobodyさん2006/07/05(水) 00:42:12ID:???
まさかと思うけど
$localsubjectmatchswitch
の初期化はきちんと入れてるよね。>>205の2行目
(>>206のchompの次の行)あたりに。
0215nobodyさん2006/07/05(水) 00:46:40ID:???
>>214のことは忘れて
02162052006/07/05(水) 00:48:32ID:???
>>214
入れてませんでした。でも入れても結果が変わらない…マッチして無いとみなされてsubject.txtに書き込まれる…
それと、なぜか一回で2重に(同じ内容が2行)書き込まれます。これもforeachあたりの間違いだと思うんだけどどこが悪いのかわからない…
アドバイスください。お願いします。
0217nobodyさん2006/07/05(水) 00:52:05ID:???
つーか$iがどこから来るのかもわからん。
0218nobodyさん2006/07/05(水) 00:56:39ID:???
ソースをうpしてくんないかな。
全容が見えなさすぎ
0219nobodyさん2006/07/05(水) 01:05:56ID:???
配列の数少なくして一回一回内容 print してデバックすればわかるだろ?w
エスパー求めすぎ。
02202052006/07/05(水) 01:23:12ID:???
>>218
http://kasamatusan.sakura.ne.jp/cgi-bin2/src/ichi42709.txt.html
ソースうpしました。アドバイスお願いします。
>>217
$iは忘れてました。つけたら少しはまともな動作をするようになりましたが求めていたものとは違いました。
0221nobodyさん2006/07/05(水) 01:44:31ID:???
my の変数の羅列で吹いたw
02222052006/07/05(水) 01:50:05ID:???
書き忘れてました。問題の部分は95行目から120行目までです
0223nobodyさん2006/07/05(水) 01:51:31ID:???
>>205 のループってさ、
@localsubject のどれかが、
@datname の最後の値 ( @datname[ $#datname ] ) にマッチしたら 1、マッチしなかったら 0
ってことなんだけど、それは処理としていいの?
どうみても @datname の最後未満の値は、マッチしようがしまいが関係ないって感じだよね。
02242052006/07/05(水) 02:27:35ID:???
>>223
>@datname の最後の値 ( @datname[ $#datname ] ) にマッチしたら 1、マッチしなかったら 0
ってことなんだけど、それは処理としていいの?

@datnameは外側のforeachでまわしてるから全部にマッチしてるかどうか確かめてあるはずですけど…
判定ルーチンが内側のforeachのすぐ後ろに来るから判定はしてくれてるはずです。

いまいろいろやって、とりあえずローカルにsubject.txtを書き出すのはうまくいったみたいです。
あとは、これが2重に書き込まれないようにするためにしないとなんだけど、そこの処理をやってるのが96〜111行目なんですよね。
で、そこがうまくいってないみたいです。$localsubjectmatchswitch=0;になるときの処理に
print "nomatch";を加えたらすでにローカルsubject.txtに書き込んである場合でもnomatchを返されました。
だからif($loopsubject=~/$loopdat/)が問題ですかね?
それとも@datanameの内容が2つあるから違うほうの内容に反応してnomatchを返すことになってるのでしょうか?
でもforeach $loopsubject(@localsubject)で内容全部まわしてるから1つでもマッチしたら2重に書き込みはされないはずですけど…
なんでまずいのかわからないのでアドバイスお願いします。
0225nobodyさん2006/07/05(水) 02:39:35ID:???
>>224
一回寝て朝もっかい考えなさい、このおバカw
0226nobodyさん2006/07/05(水) 02:42:02ID:???
1152013147.dat<>エロゲ実況 黄金の蜂蜜酒で一線越え (290)
こんなの保存して楽しいのか
0227nobodyさん2006/07/05(水) 02:55:40ID:???
どうせ print すんなら print "no match : '$loopdat'" とか書いてやれよ。
02282052006/07/05(水) 02:59:19ID:???
>>225
これが気になって眠れません。寝たほうがいいってか寝ないとなんですけど…
>>226
テスト用の検索ワードが思いつかなかったため適当に目に付いたスレを選んだのです。特に深い意味はありません。

原因が判明したっぽいです。103行目あたり、foreach $loopsubject(@localsubject){
でローカルのsubject.txtを解析するのですが、$loopsubjectをループ内でprintしてみたところ最後の1行しか表示されませんでした。
全部表示されるはずのローカルsubject.txtが表示されないということはマッチも出来ないわけですからnomatchになるということだと思います。
で、どうにかしたいんですがどうしたらいいんでしょうか?foreachで表示されないなんてことは初めてなのでわかりません。アドバイスお願いします。
0229nobodyさん2006/07/05(水) 03:04:35ID:???
> open(F,">>$localsubjectpath")||die"subject.txtをopen出来ません:$!";
> @localsubject=<F>;

これかwwwwwwww
>> とか < とかの区別もできない子だったんですね。
0230nobodyさん2006/07/05(水) 03:07:22ID:???
ただ単に「キーワードが全部含まれる」AND検索がしたいだけちゃうのかと
02312052006/07/05(水) 03:22:39ID:???
>>229
ファイルオープンの時につけるのって>と>>しか知らなかった…今ググってはじめて知った…orz
読み込みは出来るようになりました。迷惑かけて本当すみません。
でも、2重に書き込んじゃうのがどうしてもなくならないんですけどどうしたらいいんですか?
もう散々どこが悪いのか探したけどわからないんです。多分これが最後の質問です。お願いします。
0232nobodyさん2006/07/05(水) 03:33:40ID:???
>>231
直したのはわかったけど、それでマッチするようになったのかマッチしないのかぐらい書いてよ。
どうでもいいけど、 chomp $loopdat; → $loopdat =~ s/[\r\n]+$//; とかのがいいかもね。
■ このスレッドは過去ログ倉庫に格納されています