• ベストアンサー

正規表現で全角数値の検出

あるアプリで以下のような判定を行うことで全角数値をエラーとしています。しかし、実際は全角数値がきても全角数値として認識されずelse側に処理が進んでしまいます。 調べたところ下記のようなサイトが見つかり「use utf8;」が存在することで全角数値を検出できなくなっているようです。なので「use utf8;」をコメント化してみたのですが結果は同じで処理はelse側に進んでしまいました。 ※ローカル環境だと「use utf8」をコメント化すると全角数値を検出し、if文内の処理が行われる http://blog.livedoor.jp/sasata299/archives/51080322.html 何かほかに考えられる原因ってありますでしょうか? また、どうアプリにて変数$test, $test2の両方に全角数値の「1」が入っているにもかかわらず 片方は、全角数値として検出されもう片方は全角数値として検出されないという現象もありまして 変数の内容をバイナリ?で表示させて比較してみようと思うのですがどうやってやればよいでしょうか? use utf8; my $test = '1'; # 全角数値の「1」 if($test =~ /\D/) { print 'エラー'; } else { print '正常'; }

  • Perl
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8524/19375)
回答No.1

>※ローカル環境だと「use utf8」をコメント化すると全角数値を検出し、if文内の処理が行われる ソースコードを「UTF8」の文字コードで保存していないのが原因でしょう。 「use utf8」のプラグマの意味は「ソースコード内の文字列定数はUTF-8で書かれている」です。 ソースコードをシフトJISやunicodeで保存している場合、意図した動作をしません。 pealコンパイラは、use utf8と書かれていると、ソースコードの文字列定数をUTF-8で書かれていると解釈し「UTF-8から内部コードに変換する」という処理を加えてコンパイルします。 しかし、書かれている文字列定数がシフトJISだったりunicodeだったりすると、内部コードに変換せず(変換に失敗し)「変な値の半角文字列」として、何の変換もせず、そのままコンパイルします。 その結果、正規表現などが正常に機能しません。 >また、どうアプリにて変数$test, $test2の両方に全角数値の「1」が入っているにもかかわらず >片方は、全角数値として検出されもう片方は全角数値として検出されないという現象もありまして 片方は、正しく内部コード化された全角文字の「1」が格納されていて、もう片方は、内部コード化されていない環境依存の文字コードで表現された、printすると「1」が表示されるが、内部コードの「1」とは異なる文字列が格納されています(例えば、シフトJISの「1」が入っている、など) この2つの文字列を比較すれば「違う文字列」と判断されるし、片方は全角判定、もう片方は半角判定されます。 詳しくは https://www.futomi.com/lecture/japanese_utf8.html#gsc.tab=0 などを良く読んで下さい。 「なんの為にそう記述し、そう記述した効果は何なのか」を良く理解した上でソースコードを記述しましょう。

unko347
質問者

補足

ご回答ありがとうございます。 ソースコードはutf8で保存されています。 >>片方は、正しく内部コード化された全角文字の「1」が格納されていて、もう片方は、内部コード化されていない環境依存の文字コードで表現された、~ 両方の変数の値はsjisで保存された1つのファイルに定義されたものになります。 ファイルから読み込んだ値を「Encode::decode('cp932', $test)」で内部エンコーディングに変換して「if($test =~ /\D/) 」の判定をしています。 それでも全角の'1'の検出できるかできないかの差が生じてしまうようです。 尚、両方の変数を「if($test1 eq $test2)」にて比較してみましたが同じ値と判定されました。

その他の回答 (1)

  • chie65535
  • ベストアンサー率43% (8524/19375)
回答No.2

追記。 Windows環境でPerlでプログラミングしている場合、Power shellなどのコンソールは、入出力がShift_JISコードになっています。 ファイルからの入出力や、printなどのコンソール出力は、Encode::encode、Encode::decodeで「シフトJIS変換」を行う必要があります。 また、ソースコードを記述している「メモ帖」なども、無指定の場合、漢字をシフトJISで保存します。 なので、ソースコードにuse utf8と書いて、文字コードをシフトJISのままソースファイルを保存すると、Perlはソースコードを正常にコンパイルできません。メモ帳などで保存する際にはUTF-8でソースコードを保存しないとなりません。 このあたりの「文字コードの扱い」が「Perlでの最難関」になり、ここで挫ける人が多発しています。

関連するQ&A

  • 全角数値の判定

    教えて頂けますか? フォームからPOSTされた文字列が半角数値、または文字列の場合許可し、全角数値の場合拒否したいのですが 全角数値が is_numeric で数値として認識しない為 うまくいきません。 他に良い方法がありますか? よろしくおねがいします。 if ( strlen($_POST['test']) != mb_strlen($_POST['test'],'UTF-8') && is_numeric($_POST['test']) == TRUE ){ echo '半角で入力してください。<br />'; }

    • ベストアンサー
    • PHP
  • utf-8での日本語正規表現の書き方

    WindowsXPでPerlの正規表現の勉強をしています。 下記のスクリプトを作りテストしているのですが例1はマッチするのに例2はマッチしません($countが0のままです)。どうしてなのでしょうか?なおスクリプトファイルも、hoge.txtも共にUTF-8です。どなたかお教えいただけますでしょうか。どうぞよろしくお願いします。 use utf8; use encoding ("utf-8"); # 例1################################## $str1 = "そろそろ夏も終わりですね。"; $str2 = "夏"; if ($str1 =~ /夏/) { print "例1の答え: 含まれています \n"; } else { print "例1の答え: 含まれていません \n" } # 例2 ################################### $count = 0; open(FH, "C:\\temp\\hoge.txt"); while(<FH>) { if (/夏/) { $count++; } } print "$count \n";

    • ベストアンサー
    • Perl
  • 全角カタカナの正規表現

    if (preg_match('/[ァ-ヶー]+/', $value, $match )) { print ("$value"."はカタカナです。"."($match[0])"."<br />") } else { print ("$value"."はカタカナではない。<br />"); } という感じで全角カタカナにマッチさせる正規表現を使いたいのですが、このやり方だと「全角カタカナを含んでいる…」という表現になってしまいます。ある文字列が「すべて全角カタカナである」という正規表現を考えているのですが、なかなかうまくいきません。逆引きのサンプルなんかでもなかなか見つからなくて困っています。  同様に「すべて平仮名にマッチ!」というのにも応用できると思うのですが、なかなかうまく行きません。  是非、そのやり方やヒントをおしえてください。  マルチバイト対応なので[ぁ-ん]のような形で表記できます。またPerl互換(preg_match)で作っているので、Perlに詳しい方も是非是非おしえてください。

    • ベストアンサー
    • PHP
  • 正規表現の書き方に困っております。

    あるSQLのダンプを変換するプログラムをPerlで書いているのですが、 うまく正規表現が書けなくて困っております。 データの途中に,が有ると、うまくいきません。 ''の中に囲まれた,は無視するという正規表現を書きたいのです。 また、'''B'も正しく処理できれば、完璧です。 #!/usr/bin/perl use strict; use warnings; #my $a = qq{'A','B',1}; --> うまくいく  ['A']['B'][1] #my $a = qq{'A,','B',1}; --> うまくいかない ['A] ['] ['] my $a = qq{',','''B',1}; --> もっとうまくいかない ['][']['] if($a =~ /(.+?),(.+?),(.+?)/){ print "[$1]\n"; print "[$2]\n"; print "[$3]\n"; }else{ print "ERR!\n"; } exit; __END__

    • ベストアンサー
    • Perl
  • 正規表現のパターンマッチ

    配列の中から特定の文字を取り出す処理がうまくできません @test = ("aaa","bbb","t=1","v=3"," test:", " test:") 上記のような配列があったとして 一文字目がaからzで二文字目が=のものを取り出す処理と 一文字以上の空白の後ろにtest:があるものを取り出す処理は どのようにすればいいのでしょうか? 下記のような感じで書いたのですがうまくいきません @test = ("aaa","bbb","t=1","v=3"," test:", " test:") my $test = "test:"; foreach( @test ) { if( $_ =~/^[a-z]+k/) { print $_; } if( $_ =~/^\s+$test/) { print $_; } } よろしくお願いします

  • Spreadsheet::ParseExcel+正規表現?

    Excelファイルを読み込んで、A列をずら~っと上から連続して表示するプログラムを作ったのですが(下記)、句読点の"。"が入ったセルで改行したいです。しかし、うまくいきません。文字コードが原因なのかな・・・と思ってはいるのですが・・・調べても調べてもわかりません。どうか、未熟者にアドバイスお願いします。 ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ #! /usr/bin/perl # モジュールの読み込み use strict; use utf8; use Spreadsheet::ParseExcel; use Spreadsheet::ParseExcel::FmtJapan; # ? binmode STDOUT, ":utf8"; # Excelファイルの処理 my $format = new Spreadsheet::ParseExcel::FmtJapan; my $excel = new Spreadsheet::ParseExcel; my $book = $excel->Parse("xlsファイルの場所"); my $sheet = $book->{"Worksheet"}[0]; my $MaxRow = $sheet->{"MaxRow"}; my $MaxCol = $sheet->{"MaxCol"}; for(my $col=0, my $row=0; $row<=$MaxRow; $row++){ my $cell = $sheet->{"Cells"}[$row][$col]; my $val = ""; if($cell){ $val = $cell->Value; } print "$val"; if($cell=~"。"){ print "\n\n"; } } print "\n";

    • ベストアンサー
    • Perl
  • 正規表現で数値から始まりYを1字以上含む文字を判別

    数値から始まり、Yを1字以上含むものをPHPで判別させたいです。 ・最初の数値は「1~9」を扱いたいです。 ・2番目に数値がくることはありません。 ・使う文字は、数値・英字・日本語文字列・漢字・記号などあらゆる文字です。 ・使う文字は全て全角半角の両方に対応 ・全体的な数値と文字列の割合はバラバラです。 ・空白から始まっても× ・文字数制限は特にありません。 たとえば「3」から始まり「e」を含むとき 3eiklあいうeE(←○) 4yyte(←3から始まっていない×) 3rrEき134(←○) Eresry(←3から始まっていない×) 3我Ea(←○) 3aaaa(←eがない×) 3e(←○) 5Eお(←3から始まっていない×) 3E(←○) 3 E(←○)  3E(←空白から始まっている×) $str = $_GET["s"]; //3我Ea if($str{0}=="1" || $str{0}=="1"){$pattern = '/^(1|1)*.(Y|y)/';} ・・・ if($str{0}=="9" || $str{0}=="9"){$pattern = '/^(9|9)*.(Y|y)/';} if (preg_match($pattern, $str)) { echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8')."は○"; } else { echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8')."は×"; } うまくいきません。どのようにしたら良いでしょうか。

    • ベストアンサー
    • PHP
  • cgi perlの条件式にて

    変数が、数値の場合はA、それ以外はBの処理としたい場合、どのようにすればよいでしょうか。 if ($in{'volume'} == 〇〇〇){A;}else{B;} (1)全角で入力された数字も数値として扱う場合 (2)全角で入力された数字は数値として扱わない場合

    • ベストアンサー
    • Perl
  • Perl 正規表現について

    Perlに関していつもお世話になっております。 今回も正規表現に関する質問をしたいと思います。 「あ、あい、あいう、あいうえ、あいうえお」というハッシュが存在するときに、「{あ}は○○回出ました。」「{あい}は○○回出ました。」とそれぞれ表示させるコードを組もうと思います。 前回までで皆様に教えていただいたことを元に組んでみました。 #!/usr/bin/perl use warnings; use strict; use utf8; use Encode; my %word_of = ( 'あい' => 0, 'あいう' => 0, 'あいうえ' => 0, 'あいうえお' => 0, 'かき' => 0, 'かきく' => 0, 'かきくけ' => 0, 'かきくけこ' => 0, ); foreach my $search_key ( keys %word_of ) { foreach my $word ( keys %word_of ) { if ( $word =~ /$search_key/ ) { $word_of{$search_key}++; } } } foreach my $key ( sort ( keys %word_of ) ) { # utf8, shiftjis eucjp ... print encode( 'utf8', "「$key」 は $word_of{$key} 回出ました" ), "\n"; } これを出来ればeucjpで組みたいのですが、可能でしょうか? 私の思いあたる点、utf8表記の部分をeucjpに直しただけではエラーが出てしまいます。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 全角カタカナの確認

    perl 初心者です。 $str が全て全角カタカナかどうか確認したいのですがうまく行きません。 $str="アイウエオ"; などとして if ($str =~ /^[ア-ンーヽヾ]/){ print "OK\n"; } else {print "NG\n";} とすると、先頭の文字が全角カタカナかどうかの確認ができます。 ネット上の古い記事を見て if ($str =~ /^[ア-ン][ア-ンーヽヾ]+$/){ print "OK\n"; } else {print "NG\n";} としたのですが、NG になってしまいます。何処が違ってるのでしょうか。 [ア-ンーヽヾ] の部分は、「ーヽヾ」は先頭には来ないのでこうしたとのことです。 よろしくお願いしまう。

専門家に質問してみよう