17時13分31秒 [Perl/CGI]
正規表現を使ったマッチングで、「Unmatched [ in regex; marked by~」という謎のエラーメッセージが出てしまうことがあります。これは、マッチング対象の日本語文字列の文字コードがSHIFT-JISだった場合に発生します。この問題を解決するには、問題のある文字の前に「\」を付けるか、文字コードをUnicodeなどに変えてから処理を行う必要があります。
WindowsではSHIFT-JISが標準だし、UTF-8はNetscape4が読まないし…という感じで、CGIの文字コードは大抵SHIFT-JISで作ってるんですけども、SHIFT-JISの問題でまた煮詰まりました。(^^;;;
正規表現で文字列の比較を行ってる箇所で、なぜか次のようなエラーが出るのですよね。
上記のエラーは、hoge.cgiファイルの370行目でエラーですよ、という表示ですが、そのPerlソースの370行目には、次のような感じで書いてます。
正規表現を使って、変数$keywordと$checkの中身を比較しています。完全一致する場合だけ、このif文の条件式はtrueになります。
このコードは、たいていの場合にうまくいきます。
が、変数の中に日本語の文字列が入っていて、その文字コードがSHIFT-JISの場合で、「ー」とか「表」とか、特定の文字が含まれている場合に、先ほどの「Unmatched~」というエラーが出てしまいます。
この理由の説明は、以下のサイトに簡潔に書かれてますので、そっちを参照して下さい。
…とはいえ、まあいつなくなるかも分からんので、要点だけ書いておきますと。
Perlプログラム中では、「\」記号(5C)は特別な記号です。「\n」で改行を表したり、「\t」でタブを表したりするのでよく使います。
んで、日本語文字(2バイト文字)の「ー」や「表」は、SHIFT-JISコードで表現すると2バイト目が「5C」となり、「\」記号と同じになります。
だから、エラーになっちゃうのですね。
問題のある文字は、他にも、「構」(8D 5C)、「能」(94 5C)、「予」(97 5C)などがあります。
CGIでこれらの文字列をブラウザ上に表示させようと思うと、そのままでは文字化けしちゃいます。CGIをSHIFT-JISでよく記述する人は頻繁に遭遇すると思いますが。そのときは、文字化けするだけなので、エラーにはならないし、見たらすぐに分かるので修正できるのですが、正規表現でのマッチング中に出てくるとエラーが出てしまいます。(ブラウザには、Internal Server Errorと出る。)
この問題を解決するには、問題の起こる文字の直後に「\」を1個挿入してやればよいのですが、ファイルからデータを読み込んできて、一致するかどうかを調べるような、データが外部にある場合は、現実的な解決策ではありません。
やはり、文字コードを変換してから比較するしかありませんね~。
CGIの文字コードを変えなくても、一時的に、JCode.pmとかでUTF-8に変換してやるとか、もしくは、CGIモジュールのescapeメソッドでエンコードしてから比較するとかでもいいと思います。
…SHIFT-JIS、なかなか厄介ですね…。(^^;;;
この日記へのコメントはお気軽に! コメント数:4件
(前の記事) « AOLとYahoo!がメール送信者に有料の配信保証?
前後のエントリ
< 旧 / 新 >
お役に立ったようで何よりです。(^_^)
投稿者 にしし : 2008年05月19日 22:59
SHIFT_JISだと
if( $keyword =~ m/^\Q$check\E$/ ) {}
でも上手く行ったりしますね
投稿者 Anonymous : 2012年02月23日 17:27
この場合だと
if( $keyword eq $check ) {}
でしょうね
投稿者 Anonymous mkII : 2012年09月10日 09:12
コメント数: 4件
助かりました
投稿者 Anonymous : 2008年05月19日 11:05