- ベストアンサー
パターンマッチングにおいて変数を使いたい
key.csvというファイルに以下のようなデータが入っています。 U1362-2005-05-16 12:00 U1363-2005-05-16 12:00 U13255-2005-05-16 12:10 key.csvのデータ数は毎回異なります。 この各行の文字列を検索キーとして data.csvに含まれるデータとのパターンマッチングを行いたいのです。 data.csvには U1306-2005-05-16 12:00-xxx,1 U1362-2005-05-16 12:00-xxx,1 U1363-2005-05-16 12:00-xys,2 U1365-2005-05-16 12:00-xys,3 U13255-2005-05-16 12:10-yyy,1 のようにデータが入っています。 この例ではパターンマッチによって U1362-2005-05-16 12:00-xxx,1 U1363-2005-05-16 12:00-xys,2 U13255-2005-05-16 12:10-yyy,1 という結果を得たいです。 key.csvが一定のデータではないので =~//; の中に特定の数値を入れることも出来ないので、$key[0]などの変数を入れたいのですがうまくいきません。 どうしたらよいでしょうか?
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
key.csv から検索したいデータを読み込むときに改行が付いているのでそれを chomp で取り去る必要があります: open(KEY, "key.csv"); chomp(@keys = <KEY>); close(KEY); open(VAL, "data.csv"); while ($data = <VAL>) { chomp $data; for $key (@keys) { print "$data\n" and next if $data =~ /$key/; } } close(VAL);
その他の回答 (6)
- Tacosan
- ベストアンサー率23% (3656/15482)
ああ, そうそう, 配列とスカラーで同じ識別子の変数を使っても (混乱する可能性があるだけで) プログラム上は問題なしです. 念の為.
- pipipi523
- ベストアンサー率40% (148/365)
書き込んでから気が付いたのですが、 chomp();は引数を省略すると$_に対して動作するのでchomp($data);としないと意味が無いです
- pipipi523
- ベストアンサー率40% (148/365)
なぜ正規表現で動かないのか良くわかりませんが、 ダメならindex関数を使うようにしたらどうでしょう? open(IN,"key.csv"); @keydata=<IN>; close IN; open(IN2,"data.csv"); while($data=<IN2>){ chomp(); grep(index($data,$_)>=0,@keydata) && print "$data\n"; } close(IN2);
お礼
ありがとうございます。勉強になります! しかし U1362-2005-05-16 12:00-xxx,1 U1363-2005-05-16 12:00-xys,2 U13255-2005-05-16 12:10-yyy,1 という結果が得られません。 正常に動いて上の結果が出たという方いましたら、書き込みお願いします。
- ralf124c
- ベストアンサー率52% (232/446)
$dataと@dataが同一スコープ内で二重定義(スカラ型と配列型)になっています。 処理の中で「@data=split(/,/);」の行は不要かと思います。 あとはANo2さんの通りに正規表現の「or」を「|」にすれば何らかの結果はでるかと思います。
お礼
ありがとうごさいます。 二重定義(スカラ型と配列型)ですか知りませんでしたw 正規表現の「or」を「|」に修正したのですが、 U1362-2005-05-16 12:00 U1363-2005-05-16 12:00 U13255-2005-05-16 12:10 が出力されるのみで、欲しい結果は出力されません。
- pipipi523
- ベストアンサー率40% (148/365)
if($data=~/$keydata[0] or $keydata[1] or$keydata[3] /){ を if($data=~/$keydata[0]|$keydata[1]|$keydata[3]/){ に修正すれば何か表示されると思います
補足
ありがとうございます。 修正しましたが何も出力されませんでした。 if($data=~/$keydata[0]|$keydata[1]|$keydata[3]/){ を if($data=~/U1362-2005-05-16 12:00|U1363-2005-05-16 12:00|U13255-2005-05-16 12:10/){ に変えると思い通りの結果が得られるのですが、 key.csvのデータは一定ではないので、やはり変数を使用したいです。 また if($data=~/$keydata[0]/){ のように入力しても結果は得られません。 エラーもなく、空白の一行が出力されるだけです。 $keydata[3]ではなく$keydata[2]の間違えでした。
// の中に変数を使うことについては問題ないので、単純なロジックのエラーだと思います。 どう巧くいかないのか、もしくは何のエラーが出るのかを補足していただければ、また違った回答ができるかもしれません。
補足
open(IN,"key.csv"); @keydata=<IN>; print "$keydata[0]$keydata[1]$keydata[3]\n"; #検索項目確認 open(IN2,"data.csv"); while($data=<IN2>){ chomp(); @data=split(/,/); if($data=~/$keydata[0] or $keydata[1] or$keydata[3] /){ print "$data\n"; } } 初心者なので間違いだらけかもしれませんが このようにすると U1362-2005-05-16 12:00 U1363-2005-05-16 12:00 U13255-2005-05-16 12:10 だけ出力されて 肝心のパターンマッチの結果が何も出力されません。
お礼
出来ました!! ありがとうございました。 協力してくださった皆様ありがとうごさいました。 perl初めて3週間ぐらいでまだわからないことも多いです。 機会があればまたよろしくお願いします。