- 締切済み
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"; }
- みんなの回答 (7)
- 専門家の回答
みんなの回答
- kumoz
- ベストアンサー率64% (120/185)
末尾の文字列を利用すれば、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)
適当にルールを推測してやってみました。 スクリプトのここがわからないというリクエストには応えるつもりですが ルールの後出しをして修正してくれというのはやらないかもしれません。 #!/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)
えーと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)
例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、 345 777good と 380 NO 222down だけ見ればいいのでしょうか? でも345の方ってYESでもNOでもなく goodってあるんですけど。 あと前回から気になってたんですが > (-?[\d.]+) 1.23.456.78..9 みたいなのにもマッチしちゃいますよ?
- ORUKA1951
- ベストアンサー率45% (5062/11036)
>アドバイスを頂いておいて、恐縮なのですが、 すみません。今納期の限られたプグラムを製作中で、時間が取れません。 要は、345などのデータとYES,NOなどのデータの配列を作ること。 345などについては、チェック用のハッシュを作ること 行(必要なら複数行)を、そのハッシュとYES,NOなどのリストで、複数条件でチェックして、当てはまれば、そのとき使用した正規表現に当てはまった値\1,\2(Perlの場合$1,$2)を、印刷サブルーチンに渡す。 渡し方は&Sub($1,$2,$3)とか。 あとはサブルーチンで、これらを代入して印刷する。 です。
お礼
ありがとうございます。 参考にさせていただきます。
- Tacosan
- ベストアンサー率23% (3656/15482)
う~ん, どういう処理を希望してるんでしょうか? 「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可変 以上、よろしくお願いします。
- ORUKA1951
- ベストアンサー率45% (5062/11036)
数値部分だけ配列なりに入れて、サブルーチンにその数字を持って飛んだら? @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) { ***** よろしくお願いします。
補足
例によってこのデータ例を見てもどこをどのように取り出したいのかよくわからないのですが、 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 みたいなのにもマッチしちゃいますよ? → 基本そのような数字が結果として出力されないのですが、よりよい記述がありましたら お教えください。 以上、よろしくお願いします