プロが教える店舗&オフィスのセキュリティ対策術

条件分岐を使い、長いperlを簡単にまとめたいと思っています。抜粋したperlを以下にのせましたがYES/NOがずっと続いていて、メンテナンスに困っています。
どうかアドバイスをお願いします。

・データのかたち
%%%%%%%%%345 YES%%%%%%%%%%%%%%%%%%%%%%%%%
ver 3445675585950
data 111111111111
345 777good
%%%%%%%%%380 NO%%%%%%%%%%%%%%%%%%%%%%%%%%
big 2910028717721
q qtyuqqqqqqqqq
ppm 3.9999999999
380 NO 222down


・現在のperlの抜粋
#345がYESのとき
if($_ =~ /\s+345+\s+(-?[\d.]+)/){
print OUT "\n345,$1,YES";
}
#345がNOのとき
if($_ =~ /\s+345+\s+NO+\s+(-?[\d.]+)/){
print OUT "\n345,$1,NO";
}
#380がYESのとき
if($_ =~ /\s+380+\s+(-?[\d.]+)/){
print OUT "\n380,$1,YES";
}
#380がNOのとき
if($_ =~ /\s+380+\s+NO+\s+(-?[\d.]+)/){
print OUT "\n380,$1,NO";
}

A 回答 (7件)

数値部分だけ配列なりに入れて、サブルーチンにその数字を持って飛んだら?


@List = (345,348******);
foreach(@List){$ListCheck{$_}=1;}#ハッシュに入れておく
foreach (@line){
 if($_ =~ /\s+(\d+)\s+(****)/){
  $Num = $1;
  if( $2=~/([パターンマッチ]})(パターンマッチ]
    && $ListCheck{$Num} == 1) {
    *****
    &Print($Num,$Code,$ABC);
  }
}

素人くさいけど、分かりやすいかな・・
適合する数字(345とか)は、チェック用のハッシュに入れておくと早い
パターンマッチは一度で、タイムロスになる。
サブルーチンに渡すときに印刷項目も渡す

この回答への補足

アドバイスありがとうございます。
アドバイスを頂いておいて、恐縮なのですが、
「Unrecognized character \x81 at test.pl line 8.」と文法エラーが
このライン「if($_ =~ /\s+(\d+)\s+(****)/){」で発生します。(**)の箇所を変更してもでます。

それと、下記部分ですが具体的に****とパターンマッチの箇所は
どのように書けばよろしいのでしょうか?
if( $2=~/([パターンマッチ]})(パターンマッチ]
    && $ListCheck{$Num} == 1) {
    *****
よろしくお願いします。

補足日時:2008/10/22 23:06
    • good
    • 0

末尾の文字列を利用すれば、YES/NO の判定ができるのではないかと思います。



%judge = (good => 'YES', up => 'YES', down => 'NO');

while (<FH>) {
print OUT "\n$1,$judge{$4},$3" if /^(\d+)\s+(NO\s+)?(\d+)([a-z]+)/;
}
    • good
    • 0

適当にルールを推測してやってみました。



スクリプトのここがわからないというリクエストには応えるつもりですが
ルールの後出しをして修正してくれというのはやらないかもしれません。

#!/usr/bin/perl
# -*- coding: utf8 -*
use strict;
use warnings;
use feature ':5.10';

my $yesno = '';
my $number = 0;

while (my $line = <DATA>) {
if ($line =~ /^%+ (\d{3}) \s+ (YES|NO)/x) {
$number = $1;
$yesno = $2;
next;
}
if ($line =~ /^ $number (?:\s+ (NO))? \s+ (\d+)/x) {
my $t = $yesno;
if ($yesno eq 'NO' && !defined $1) {
$t = 'YES';
}
printf "%3d,%s,%s\n", $number, $t, $2;
}
}


__END__
%%%%%%%%%345 YES%%%%%%%%%%%%%%%%%%%%%%%%%
ver 3445675585950
data 111111111111
345 777good
345 999good
345 000good
%%%%%%%%%380 NO%%%%%%%%%%%%%%%%%%%%%%%%%%
big 2910028717721
q qtyuqqqqqqqqq
ppm 3.9999999999
380 NO 222down
380 111up

実行結果:
345,YES,777
345,YES,999
345,YES,000
380,NO,222
380,YES,111
    • good
    • 0

えーとgoodやらdownやらがついている行には、NOの場合はそれが含まれるけど、


YESは含まれない。と。
NOがないときはYESとみなすというのはダメなんですか?

>あと前回から気になってたんですが
>> (-?[\d.]+)
>1.23.456.78..9 みたいなのにもマッチしちゃいますよ?
>→
>基本そのような数字が結果として出力されないのですが、よりよい記述がありま
>したらお教えください。

どこまで厳しく見るかとかありますけど

[+-]?\d+\.\d+

とか。
.234
123
みたいのも拾いたいというのならもうちょっとややこしくなりますが、
あるいはモジュールに任せるというのもありでしょう。

Regexp::Common::number -- provide regexes for numbers - search.cpan.org
http://search.cpan.org/~abigail/Regexp-Common-2. …
    • good
    • 0

例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、



345 777good

380 NO 222down
だけ見ればいいのでしょうか?
でも345の方ってYESでもNOでもなく goodってあるんですけど。

あと前回から気になってたんですが
> (-?[\d.]+)
1.23.456.78..9 みたいなのにもマッチしちゃいますよ?

この回答への補足

例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、

345 777good

380 NO 222down
だけ見ればいいのでしょうか?
でも345の方ってYESでもNOでもなく goodってあるんですけど。


出力したいのはgame数「345」「380」とそのgame数の判定結果「YES」「NO」と
その時の詳細結果「777good」「999good」「222down」です。
また、最初に提示したデータに誤りがあります。345や380の詳細結果は複数あります。
イメージは
345,YES,777(goodは削除)
345,YES,999(goodは削除)
345,YES,000(goodは削除)
380,NO,222(downは削除)
380,YES,111(upは削除)
です。
%%%%%%%%%345 YES%%%%%%%%%%%%%%%%%%%%%%%%%→345固定,YES可変
ver 3445675585950            →可変
data 111111111111            →可変
345 777good             →345固定,777good可変
345 999good             →345固定,999good可変
345 000good             →345固定,000good可変
%%%%%%%%%380 NO%%%%%%%%%%%%%%%%%%%%%%%%%%→345固定,NO可変
big 2910028717721 →可変
q qtyuqqqqqqqqq →可変
ppm 3.9999999999 →可変
380 NO 222down →380固定,222down可変,判定がNOときのみgame数と詳細データの間にNOが入る
380 111up →380固定,111up可変

あと前回から気になってたんですが
> (-?[\d.]+)
1.23.456.78..9 みたいなのにもマッチしちゃいますよ?

基本そのような数字が結果として出力されないのですが、よりよい記述がありましたら
お教えください。

以上、よろしくお願いします

補足日時:2008/10/23 04:29
    • good
    • 0

>アドバイスを頂いておいて、恐縮なのですが、


すみません。今納期の限られたプグラムを製作中で、時間が取れません。
要は、345などのデータとYES,NOなどのデータの配列を作ること。
345などについては、チェック用のハッシュを作ること
行(必要なら複数行)を、そのハッシュとYES,NOなどのリストで、複数条件でチェックして、当てはまれば、そのとき使用した正規表現に当てはまった値\1,\2(Perlの場合$1,$2)を、印刷サブルーチンに渡す。
渡し方は&Sub($1,$2,$3)とか。
あとはサブルーチンで、これらを代入して印刷する。
です。
    • good
    • 0
この回答へのお礼

ありがとうございます。
参考にさせていただきます。

お礼日時:2008/10/23 04:17

う~ん, どういう処理を希望してるんでしょうか?


「345」や「380」, あるいは「YES」や「NO」がどこから来たものなんでしょうか?
また, これらの値は固定でしょうか, それとも可変でしょうか?

この回答への補足

ありがとうございます。

ご質問に対して、回答します。
う~ん, どういう処理を希望してるんでしょうか?
→出力したいのはgame数「345」「380」とそのgame数の判定結果「YES」「NO」と
その時の詳細結果「777good」「999good」「222down」です。
また、最初に提示したデータに誤りがあります。345や380の詳細結果は複数あります。
イメージは
345,YES,777(goodは削除)
345,YES,999(goodは削除)
345,YES,000(goodは削除)
380,NO,222(downは削除)
380,YES,111(upは削除)
です。

「345」や「380」, あるいは「YES」や「NO」がどこから来たものなんでしょうか?
→以下を参照ください

また, これらの値は固定でしょうか, それとも可変でしょうか?
→以下を参照ください

%%%%%%%%%345 YES%%%%%%%%%%%%%%%%%%%%%%%%%→345固定,YES可変
ver 3445675585950            →可変
data 111111111111            →可変
345  777good             →345固定,777good可変
345  999good             →345固定,999good可変
345  000good             →345固定,000good可変
%%%%%%%%%380 NO%%%%%%%%%%%%%%%%%%%%%%%%%%→345固定,NO可変
big 2910028717721 →可変
q qtyuqqqqqqqqq →可変
ppm 3.9999999999 →可変
380  NO  222down →380固定,222down可変,判定がNOときのみgame数と詳細データの間にNOが入る
380   111up →380固定,111up可変

以上、よろしくお願いします。

補足日時:2008/10/23 04:20
    • good
    • 0

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