- ベストアンサー
「ー」を削除するとスカラーの頭の0が消えてしまいます
2つの外部テキストを読み込んで、電話番号を頼りにコード番号と電話番号を結びつけるCGIを作ろうとしています。 その2つのテキストファイルはそれぞれ既製のCGIが書き出すものなのでそのフォーマットが変えられないのですが、下のように、片方は電話番号がハイフォン入りで、もう片方はハイフォンなしのものなので単純に「if ($a eq $B)......」では合致するものを抽出できません。 コード,電話番号,生年月日 01491,03-5432-1234,19981224 74465,06-9876-0001,19981224 ・ ・ 電話番号,メールアドレス,生年月日 0354321234,abc@okwave.ne.jp,19981224 0698760001,wxyz@goo.jp,19981224 ・ ・ そこで片方のテキストファイルから読み込んだデータから「ー」を削除してやろうと、 $denwa =~ s/-//g; という行を入れました。 しかし、これを実行した結果マッチするデータが出てこなかったので$denwaの中身が同変換されているかを確認したところ、「03-5432-1234」は「0354321234」とならずに「354321234」になってしまっていました。 私はPerlの知識が非常に浅いので、「$」がついているからには数値でなく文字列のはずだから頭の「0」は消えないだろうと思っていたのですが、「$denwa =~ s/-//g;」なんて形でハイフォンを削除すると数値扱いになってしまうのでしょうか? この電話番号には時々頭に国番号がついて「494332112233」のようになることもあるので、頭にゼロがないデータに単純に0を付け加えるということも出来ません。 ハイフォンの削除処理をしても頭の「0」が消えないようにする方法はないでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
既に回答にある通り頭の'0'が消えてしまったのは どこかで一回数値として評価されてしまったからだと思われます。 awkから引き継いだ仕様で、数値のように見える文字列は その文脈によって、数値になったり文字列になったりします。 ですので、"0123" という文字列を内容として持つ 変数を数値として扱われる文脈で扱うと、 use strict; my $numstr = "01234"; print $numstr, "\n"; $numstr *= 1; print $numstr, "\n"; 01234 1234 となります。 #2のお礼にあるスクリプトに、質問にあるデータを 食わせてみたのですが、おっしゃる現象がでませんでした。 もしよろしければ再現できるデータを提示していただけませんか? #本番で使用するデータでなくて良いです。
その他の回答 (2)
- kabaokaba
- ベストアンサー率51% (724/1416)
具体的にどうやってるんですか? #ActivePerl 5.8.8 use strict; use warnings; my $data="01491,03-5432-1234,19981224"; my $telnum= (split/,/, $data)[1]; $telnum=~s/-//g; print $telnum; これだと 0354321234 と出てきます. >「$」がついているからには数値でなく文字列のはずだから これは間違いです. $がついてるのは「スカラー」であって 場所に応じて数値になったり文字になったりします. また,正規表現は文字列に対する操作ですから 普通は文字列として扱われます.
お礼
お返事をどうもありがとうございます。 > $がついてるのは「スカラー」であって > 場所に応じて数値になったり文字になったりします. そ…そうだったんですか。 「スカラー」=「文字列」なんだと思っていました。 お恥ずかしい…。 my $file = 'data/shain.csv'; # 読み込むファイル名 open(my $fd, $file); foreach (<$fd>) { chop; my @cols = split("\,", $_); $aidhi = $cols[0] if $in{'email'} eq $cols[2]; # 3桁目がメアド一致ならID取得 $denwa = $cols[1] if $in{'email'} eq $cols[2]; # 3桁目がメアド一致ならTEL取得 $denwa =~ s/-//g; $aidhi = "Tel Not Found" if $in{'電話'} ne $denwa; # 3桁目がメアド一致ならID取得 } close($fd); # ファイルを閉じる if ($aidhi eq "Not Found") { &error("該当する社員番号が見つかりませんでした"); } if ($aidhi eq "Tel Not Found") { &error("電話番号とメールアドレスが一致しません"); } としているんですが、これで結果が必ず「電話番号とメールアドレスが一致しません」になってしまうので、最後の1行「if ($aidhi eq "Tel Not Found") { &error("電話番号とメールアドレスが一致しません"); }」を「if ($aidhi eq "Tel Not Found") { &error($denwa); }」とした上でわざとエラーの出る間違った電話番号を入力して$denwaの内容を見てみました。 すると、この「$denwa =~ s/-//g;」をなくすと$denwaは「03-5432-1234」と出てくるのに、「$denwa =~ s/-//g;」つきだと「354321234」と出てきたので不思議で仕方がないのです。
- calltella
- ベストアンサー率49% (317/635)
とりあえずヒントです。 $denwa = 'hoge'.$denwa; $denwa =~ s/-//g; 電話番号のの前に文字列を入れて変換してみましょう。 おそらく'hoge0354321234'になるハズです。 という事は・・・・数字として認識しているのだと思います。
お礼
早々のお返事をどうもありがとうございます。 はい、前に別の文字列を加えたらおっしゃるようになりました。 やっぱり数値になってしまっているんですね。
お礼
お返事ありがとうございました。 「補足要求」とのことですが、頂いたこのお返事で既にとても良いヒントを頂き、解決しました! 実は#2のお礼に欠かせて頂いたソースには一ヶ所サブルーチンに飛ぶ部分があり、その飛んだ先は「この部分は関係ないだろう」と思って省略した著作権のある外部ファイルでした。 requireで読み込むそのサブルーチンには $shubetsu = index $torikomi , "-" ; if ($shubetsu < 2) {$renrakusaki *= 1; } という部分があり、この「$torikomi」と「$renrakusaki 」は電話番号のデータと値をやり取りしています。 ここで数値化されてしまっていたようです。 私はこの >$numstr *= 1; といった記述を知らなかったので、これを軽視してしまったのが間違いの元でした。 おかげさまで助かりました。 どうもありがとうございました!