にしし ふぁくとりー(西村文宏 個人サイト)

Presented by Nishishi via Movable Type. Last Updated: 2015/09/22. 13:24:14.

マッチングでエラー「Unmatched [ in regex; marked by~」

正規表現を使ったマッチングで、「Unmatched [ in regex; marked by~」という謎のエラーメッセージが出てしまうことがあります。これは、マッチング対象の日本語文字列の文字コードがSHIFT-JISだった場合に発生します。この問題を解決するには、問題のある文字の前に「\」を付けるか、文字コードをUnicodeなどに変えてから処理を行う必要があります。

WindowsではSHIFT-JISが標準だし、UTF-8はNetscape4が読まないし…という感じで、CGIの文字コードは大抵SHIFT-JISで作ってるんですけども、SHIFT-JISの問題でまた煮詰まりました。(^^;;;

正規表現で文字列の比較を行ってる箇所で、なぜか次のようなエラーが出るのですよね。

Unmatched [ in regex; marked by <-- HERE in m/^■■■ <-- HERE ■■■ / at hoge.cgi line 370.

上記のエラーは、hoge.cgiファイルの370行目でエラーですよ、という表示ですが、そのPerlソースの370行目には、次のような感じで書いてます。

if( $keyword =~ m/^$check$/ ) {

正規表現を使って、変数$keywordと$checkの中身を比較しています。完全一致する場合だけ、このif文の条件式はtrueになります。

このコードは、たいていの場合にうまくいきます。
が、変数の中に日本語の文字列が入っていて、その文字コードがSHIFT-JISの場合で、「ー」とか「表」とか、特定の文字が含まれている場合に、先ほどの「Unmatched~」というエラーが出てしまいます。

この理由の説明は、以下のサイトに簡潔に書かれてますので、そっちを参照して下さい。

基礎プログラミング(FAQ)

…とはいえ、まあいつなくなるかも分からんので、要点だけ書いておきますと。
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、なかなか厄介ですね…。(^^;;;

コメント

助かりました

投稿者 Anonymous : 2008年05月19日 11:05

お役に立ったようで何よりです。(^_^)

投稿者 にしし : 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件

コメント投稿欄 この日記に対するコメント投稿を歓迎します。

保存しますか?



※本文中にURLは書けません。(書くと投稿が拒否されますのでご注意下さい。)

※投稿内容は、実際にページ上に掲載される前に、管理者によって確認される設定にしている場合があります。その場合は、投稿後にその旨が表示されます。たいてい1~2日以内には表示されるはずですので、気長にお待ち願います。m(_ _)m

トラックバック

このエントリーへのトラックバックURLを表示するにはここをクリック
※スパム防止のため、トラックバックURLは別ウインドウで表示します。(JavaScriptが有効でないと表示されません。)

--- 当サイト内を検索 ---