• 締切済み

perlの条件分岐について

条件分岐を使い、長い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"; }

みんなの回答

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.7

末尾の文字列を利用すれば、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]+)/; }

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

適当にルールを推測してやってみました。 スクリプトのここがわからないというリクエストには応えるつもりですが ルールの後出しをして修正してくれというのはやらないかもしれません。 #!/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

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

えーと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.122/lib/Regexp/Common/number.pm

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、 345 777good と 380 NO 222down だけ見ればいいのでしょうか? でも345の方ってYESでもNOでもなく goodってあるんですけど。 あと前回から気になってたんですが > (-?[\d.]+) 1.23.456.78..9 みたいなのにもマッチしちゃいますよ?

noname#72292
質問者

補足

例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、 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 みたいなのにもマッチしちゃいますよ? → 基本そのような数字が結果として出力されないのですが、よりよい記述がありましたら お教えください。 以上、よろしくお願いします

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.3

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

noname#72292
質問者

お礼

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

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

noname#72292
質問者

補足

ありがとうございます。 ご質問に対して、回答します。 う~ん, どういう処理を希望してるんでしょうか? →出力したいのは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可変 以上、よろしくお願いします。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.1

数値部分だけ配列なりに入れて、サブルーチンにその数字を持って飛んだら? @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とか)は、チェック用のハッシュに入れておくと早い パターンマッチは一度で、タイムロスになる。 サブルーチンに渡すときに印刷項目も渡す

noname#72292
質問者

補足

アドバイスありがとうございます。 アドバイスを頂いておいて、恐縮なのですが、 「Unrecognized character \x81 at test.pl line 8.」と文法エラーが このライン「if($_ =~ /\s+(\d+)\s+(****)/){」で発生します。(**)の箇所を変更してもでます。 それと、下記部分ですが具体的に****とパターンマッチの箇所は どのように書けばよろしいのでしょうか? if( $2=~/([パターンマッチ]})(パターンマッチ]     && $ListCheck{$Num} == 1) {     ***** よろしくお願いします。

関連するQ&A