perlにてログの解析プログラムを作成しております。
ログは各データの区切り文字がスペースで出力されます。
その為、例えば文字列で「プログラムの異常が発生しました (発生ノード)」が出力されている場合split関数によって配列に格納しようとすると「プログラムの異常が発生しました」と「(発生ノード)」に分解されて格納されてしまい後ほどの処理に影響が出てしまいます。ログの仕様として文字列を出力するときには直前に文字列の長さを提示しております。例えば「43 プログラムの異常が発生しました (発生ノード)」のような形で出力されます。これらの条件で文字列を一つの配列に格納するにはどのようなプログラムを組めばよろしいでしょうか。

現時点で考えているのは文字列の長さが出ているのでその回数分文字を1文字づつ読み込むことを考えております。ただし全角と半角の区別が自動でついてしまうと厄介なので全部半角として取り込めないかなどを検討しております。
なにか他にいいアイデアがありましたら教えてください。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

一般的に、スプリットさせる区切り文字には、



<>

を使います。
callhiro さんが言われるように、
スプリットの区切りを変えた方が早いと思いますよ。
    • good
    • 0
この回答へのお礼

substr関数を使うとうまくいきました。
実際のプログラムは以下のようにしました。

@log_split = split(/ /,$logdata,2);
$logdata[0] = substr($log_split[1],0,$log_split[0]);
$logdata[1] = substr($his_002[1],$his_002[0]);
print "メッセージ内容<BR>\n";
print "<FONT COLOR=\"$font_color\">$logdata[0]</FONT><BR>";
print "<BR>\n";

これで残りのデータは$logdata[1]に入るので活用できます。

お礼日時:2001/07/02 15:37

区切り文字をスペースじゃなくしたほうがいいんじゃないですか?

    • good
    • 0
この回答へのお礼

区切り文字が<>等で出てくれると助かるのですが別のアプリケーションがだしているログをperlで解析しようとしているので四苦八苦しています。例えばsyslogのメッセージの統計を取ろうとした時に単純にスペースを区切り文字にできないですよね。

お礼日時:2001/07/02 15:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QEUCで出力されるプログラムをS-JISで出力するようにしたい。

perlはまだかじる程度です。

あるサイトで配布されていたプログラムを使用していたのですが、
このプログラムでは、出力されるdatファイル(テキストファイル)がEUCで出力されます。
これをShift-JISで出力させたいんですが…できるんでしょうか。

Aベストアンサー

こんにちは。
「かじる程度」という事なので。もうちょっとだけかじれる程度の私が(^^;

エディターは何をお使いですか? コードを指定して保存できる物でしょうか?
出来ないのであれば、ひとまず
http://www.k-collect.net/program.htm

68行目の
$CharSet = 'EUC-JP'; # 漢字コード
$Encoding = 'euc';

$CharSet = 'shift_jis'; # 漢字コード
$Encoding = 'sjis';
へ変更

1410行目の
print " <META http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\">\n";

print " <META http-equiv=\"Content-Type\" content=\"text/html; charset=shift_jis\">\n";
へ変更

これで、プログラムをshift_jisで保存、運用するとlogはshift_jisで
出来ると思います。

こんにちは。
「かじる程度」という事なので。もうちょっとだけかじれる程度の私が(^^;

エディターは何をお使いですか? コードを指定して保存できる物でしょうか?
出来ないのであれば、ひとまず
http://www.k-collect.net/program.htm

68行目の
$CharSet = 'EUC-JP'; # 漢字コード
$Encoding = 'euc';

$CharSet = 'shift_jis'; # 漢字コード
$Encoding = 'sjis';
へ変更

1410行目の
print " <META http-equiv=\"Content-Type\" co...続きを読む

Q配列に格納した文字列の置換

Perlで、配列@arrayの要素それぞれを文字列$strから見つけてタグで囲みたいと思っています。

$str = 'abc+fghoge(ij';
@array = ('+', '(', '?', '//', 'hoge');

$pattern = '\Q' . join '\E|\Q', @array . '\E';
$str =~ s/($pattern)/<TAG>$1<\/TAG>/g;

@arrayの要素には、メタキャラクタが含まれる可能性があるため、\Qと\Eで挟む必要があるかと思うのですが、上のようにしてもうまくいきません。下だとうまく置換されるので、\Qや\Eの使い方は間違っていないと思うのですが、どなたかアドバイスいただけないでしょうか。

$str =~ s/(\Q+\E|\Q(\E|\Q?\E|\Q//\E|\Qhoge\E)/<TAG>$1<\/TAG>/g;

よろしくお願いします。

Aベストアンサー

$pattern = '\Q' . join '\E|\Q', @array . '\E';

$pattern = '\Q' . join('\E|\Q', @array) . '\E';

としないと多分希望した文字列にはなりません。
しかしそれでも希望の動作はしませんその理由は

$patttern2 = "\Q+\E|\Q(\E|\Q?\E|\Q//\E|\Qhoge\E";
として、
$patternと$pattern2を出力して違いを見てください。

要は正規表現のメタキャラクタをエスケープしたものを'|'で
繋げてやればよいので、

$pat2 = join('|', map {quotemeta $_} @array);

のようにすればよいと思います。
単純に'|'で繋いだ文字列を構築するのはマッチングが遅かったり
するので改良の余地はありますが、とりあえず。

Q&(半角アンド)が含まれる文字列の分割

http://oshiete1.goo.ne.jp/kotaeru.php3?q=644082
質問したものです。

&が%26なのはわかったのですが、それを分割する術がわかりません。
ただ普通にsplitでやってしまうと意図しない&で切れてしまいます。
どのようにしたらいいですか?

Aベストアンサー

URLデコード前に&を使って分けましょう。
そして連想配列(ハッシュ)に突っ込みましょう。
で、煮るなり焼くなりした方がいいです。(というかそれが普通です)
見たところ、遠回りなことやってますよ。

read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
foreach $pair (split(/&/,$buffer)){
($name,$value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

それと、配列なのに
> @filew = "$TITLETITLE=$TITLE&$DATETITLE=$DATE&……\n";
とやっている意味が不明です。
これなら普通に変数に代入するべき。
で、使いまわさないなら
print FH "$TITLETITLE=$TITLE&$DATETITLE=$DATE&……\n";
とやった方がメモリを無駄に消費せずに済みます。

最後に、日本語が混ざったりするならjcode.plなりJcode.pmに通した方が身のためですよ。(ぉ)

URLデコード前に&を使って分けましょう。
そして連想配列(ハッシュ)に突っ込みましょう。
で、煮るなり焼くなりした方がいいです。(というかそれが普通です)
見たところ、遠回りなことやってますよ。

read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
foreach $pair (split(/&/,$buffer)){
($name,$value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

それと、配列なのに
> @filew = "$TITLETITLE=$TITLE&...続きを読む

Q文字列が6文字の半角スペースかどうかを判断する方法

$mno = substr($buf,0,6);

if ($mno eq ' '){
&error(4);
} else {
・・・・・・・・
・・・・・・・・
}

と、上記のような感じでロジックをくんでいるですが、
$mno が6文字分の半角スペースの時はエラーサブにとびたいのですが、うまく飛びません。
上記のようなロジックであっているのでしょうか?
それとも、「eq」や「ne」では比較できないのでしょうか?

Aベストアンサー

このページで半角スペースを表すのは難しいので、ここではあえて半角スペースを 「.」 で表させて頂きます。
質問者さんのソースの通り、

$buf = '......abcdefg'; #最初の6文字が半角スペースの適当な文字列
$mno = substr($buf,0,6);

if ($mno eq '......'){
&error(4);
} else {
#ほにゃらら
}

で一応動きましたよ~(Active Perl)。全角スペースだったっとかいうオチは無いですよね。念のため$bufの中身のご確認を・・・。

Q文字列検索(例えばindex関数)をバイト単位で行いたい

やりたいことは日本語文字列の処理で、特定の文字を切り抜きたいのですがうまくいきません。
なぜなら、文字列を切り抜くsubstr関数がバイト単位であるのに対し、文字列を検索するindexがバイト単位でおこなわれていないからです。

例:
文字列"12万3456円"から、円だけを取り除きたいとします。

$str = "12万3456円";
$index = index($str,"円");
$newStr = substr($str, 0, $index);

indexは7を返すが、substrで0から7番目を切り取っても、バイト単位なのでうまくいきません。

文字列の検索をバイト単位で行う方法を教えてください。
おねがいします。

Aベストアンサー

そもそも何でバージョンをかかない?

Perl5.8.8だと

$str = "12万3456円";
$index = index($str,"円");
$newStr = substr($str, 0, $index);
print $newStr;

だけでもSJISでも期待の動きをする.
#まあ,危ない文字だと動かないだろうから
#各種プラグマの類は書くべきだけど

けど・・そもそも正規表現にしない事情がまるでわからない

最近のPerlだとベースがUTF8だから
日本語がどーのこーのとか二バイトがどーのこーのは
基本的にはない.


このカテゴリの人気Q&Aランキング

おすすめ情報