質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Q&A

2回答

1026閲覧

perlでの正規表現マッチング「ソ」に関して

gen0825

総合スコア15

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

0グッド

1クリップ

投稿2018/02/22 02:26

初めまして、perlの初心者です。
現在、perl(cgiファイル)でマイページの個人情報の登録画面を作成しております。
フリガナを登録する画面で、チェックを入れて漢字はエラーメッセージを出すというものを作成しております。
そこで、カタカナの「ソ」を入れると漢字と認識されて、エラーメッセージが表示されてしまいます。
そこで、対処法としてカタカナの「ソ」をマッチングさせて、チェクの時のみ「ソ」を削除した状態でチェックを行おうと考えております。
この「ソ」が漢字と認識される現象はSJIS特有の物みたいですのでSJISからUTF-8にして、チェックを行っておりますが下記エラーが出てうまくいきません。
間違っている部分や、もっとこうした方が良い部分がありましたら、お教えいただけませんでしょうか。
よろしくお願いいたします。

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at support@sakura.ad.jp to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.

言語はperlで文字コードはSJISで作成しております。

perl

1$in{'KANA'} = decode('UTF-8', 'shift'); 2$in{'KANA'} = decode_utf8($in{'KANA'}); 3$in{'KANA'} =~ s/ソ//g;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

投稿2018/02/22 03:55

KojiDoi

総合スコア13669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

原因は、ShiftJISの「ソ」の中に、エスケープ文字(0x5c)が含まれるためです。ShiftJISであれば円記号、ASCIIであればバックスラッシュに相当するものです。ShiftJISにはこうした文字が他にも存在します。

ShiftJISの「ソ」は、オクテット列として見ると0x83,0x5cで、後半にエスケープ文字があります。エスケープ文字というのは、ご存知の通り、その後ろのメタ文字をエスケープする効果があります。この例で言うなら、置換で使用している中央のスラッシュをエスケープしていることになります。つまり、本来 s/A/B/ のようになっているべきところ、 s/A/B/ として認識されるため、文法エラーとなります。

utf8対応されているPerlをご利用であれば、「ソ」を無理やり消そうとするのではなく、Perlの内部表現に置き換えてマッチさせるのが簡単かと思います。

Perl

1use Encode; 2 3print check_katakana( '漢字' ) ? "OK\n" : "NG\n"; # => NG 4print check_katakana( 'ひらがな' ) ? "OK\n" : "NG\n"; # => NG 5print check_katakana( 'カタカナ' ) ? "OK\n" : "NG\n"; # => OK 6print check_katakana( 'ドレミファソ\ラシド' ) ? "OK\n" : "NG\n"; # => OK 7print check_katakana( 'カナ混じり' ) ? "OK\n" : "NG\n"; # => NG 8 9sub check_katakana { 10 my $word = shift; 11 my $utf8_word = decode('shiftjis', $word); 12 return $utf8_word =~ m{^\p{sc:Kana}+$}; 13}
  • スクリプトはsjisで保存されているものと想定
  • 正規表現はUnicodeプロパティで指定

cf. Unicodeプロパティを使ったPerl正規表現

スクリプトファイルの保存文字セットにこだわりがないなら、全体をutf8で保存し、Perlの標準的な内部表現を活用するほうが、今回のような思わぬトラブルが少ないです。

ところで、Encode.pmのdecodeは、「指定の文字セットで内部表現に変換する」関数です。例えばdecode('shiftjis', $word)は、「$wordをshiftjisとみなしてPerl内部表現(utf8フラグの付いた文字列)へ変換する」となります。あくまでも内部表現の介在するものなので、オクテット列からオクテット列に変換するものではないこと、ご注意ください。

投稿2018/02/28 14:03

編集2018/02/28 14:23
aql

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問