プロが教えるわが家の防犯対策術!

Perlでフォームに入力された値をチェックするとき、入力される文字列は半角文字以外を入力されるとエラーになるスクリプトを書きたいと思っています。
(ただし、半角に出来る文字「カタカナ、記号等」は半角に変換するのでエラーでは無いとしたいです)

どうすれば実現出来るでしょうか。
よろしくお願いします。

A 回答 (4件)

パターンマッチを利用することをオススメします。


とりあえず、余計なマッチミスを防ぐためにも、EUCコードに変換してから処理を行います。
参考URLのページに詳しく解説されています。
参考URLのページをみても分からなければ、補足をお願いします。

一応、主要な文字コードのパターンを記しておきます。
$nobashi = '(?:\xA1[\xBC\xBD\xC1])'; # ー-~
$kigo = '(?:[\xA1\xA2][\xA1-\xFE])'; # 全角の記号
$suuji = '(?:\xA3[\xB0-\xB9])'; # 0-9
$alphabet = '(?:\xA3[\xC1-\xDA\xE1-\xFA])'; # 全角英字
$alpha_big = '(?:\xA3[\xC1-\xDA])'; # 全角英字(大文字A-Z)
$alpha_small = '(?:\xA3[\xE1-\xFA])'; # 全角英字(小文字a-z)
$hiragana = '(?:\xA4[\xA1-\xF3])'; # ぁ~ん
$katakana = '(?:\xA5[\xA1-\xF6])'; # ァ~ヶ

参考URL:http://www.din.or.jp/~ohzaki/perl.htm

この回答への補足

回答ありがとうございます。

参考URLを見てやってみたのですがうまくいきません。
カタカナが1文字の時はうまく行くようなのですが、複数のカタカナになった場合、失敗します。
文字コードは全てEUCで行っています。

以下がやろうとしている手順です。

1.全角文字を半角文字へ変換する

2.チェックを行う

#1バイト文字以外の時
if($buf !~ /[\x00-\x7F]/){
  #半角カタカナ以外のとき
  if($buf !~ /(?:\x8E[\xA6-\xDF])/){
    print "NG\n";
    exit;
  }
}
print "OK\n";

どこがおかしいのでしょうか。
正規表現はまだよく分かっていないためご迷惑をおかけしますがよろしくお願いします。

補足日時:2002/01/22 09:17
    • good
    • 0

参考URLの「日本語を扱う」の項の「正しくパターンマッチさせる」の部分を読まれたでしょうか?


http://www.din.or.jp/~ohzaki/perl.htm#JP_Match

私もこのページにはよくお世話になります(^^;
ここに書かれたとおり、文字コードを指定するだけではうまく行かないのです^^;

後、前の書き込み時には忘れていたのですが、
私の書いた全角の記号には半角に変換出来ない記号も含まれます。とりあえず、文字コードを調べられるソフトで変換の対象にしたい文字のコードを調べてください^^;
私は プレジャースカイという会社の フリーソフトhttp://www.pleasuresky.co.jp/ を使わせて頂いてます。

>修飾子 g (処理の対象を全域にする)を使ってください
は単に含まれるかを調べる場合、必要ありません。
abc に b というパターンがマッチします。
perl -e "$str='abc'; print 'Match!' if $str =~ /b/;"
プロンプトから実行してみてください。
「プロンプト」というのは、ちなみに、Win9X系だと、DOSプロンプト、WinNT系だと、コマンドプロンプトと呼ばれる物です。Linuxだったらターミナル(エミュレータ)です。念のため^^;

参考URL:http://www.din.or.jp/~ohzaki/perl.htm#JP_Match, http://www.pleasuresky.co.jp/

この回答への補足

回答ありがとうございます。
下で書いたコードですが間違っていたようです。
みなさんのアドバイスを受けながらいろいろ考えてみたのですがとりあえず、以下のコードでうまく動いているようです。

sub Check{
  ($buf) = @_;

  #1バイト文字を消す
  $buf =~ s/[\x00-\x7F]//g;
  #半角カタカナを消す
  $buf =~ s/(?:\x8E[\xA6-\xDF])//g;
  #まだ文字が残っていればエラーとする
  if(length($buf) == 0){
    return "OK";
  }else{
    return "NG";
  }
}

感覚的にあまりよい回答では無いと思うのですが。
もし、もう少しよい回答があれば教えていただけるとうれしいです。

補足日時:2002/01/23 10:36
    • good
    • 0
この回答へのお礼

> 参考URLの「日本語を扱う」の項の「正しくパターンマッチさせる」の部分を読まれたでしょうか?

読ませていただきました。
難しいですね。文字の奥の深さが分かります。
少しずつ理解していきたいと思います。
[g]の件もありがとうございました。

これからも質問等するかもしれませんがよろしくお願いします。

お礼日時:2002/01/23 11:09

全角カナと半角カナの並びは違うので、変換しようと思ったらパターンを配列に記述するしかないと思います。


私は逆のこと、つまり半角カナを全角カナに直すとか勉強してました。

$moji = 'ホゲ';

@base = ('ア', 'イ',・・・'ァ'・・・);
@change = ('ア', 'イ',・・・'ァ'・・・); #←ホントは半角

for($n = 0; $n < @base; $n++){
$moji =~ s/$base[$n]/$change[$n]/g;
}

とかやってできると思ったら、大間違いでした!
ある文字の2バイト目と次の文字の1バイト目を1文字としてマッチしてしまうのです。
難しいところです。
ほかの方の参考URLなどもみて、お互いがんばって勉強しましょう。

ちなみに、このOKWEBも指摘するように、半角カナは機種依存文字なので使わないほうがいいです。
半角って言ってもEUCでは2バイトだし・・・。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

半角カタカナはWebでは使わない方がいいのは分かっているのですが、プログラムの仕様上どうしても半角カタカナを使用しなければいけないんです。

上に作成してみたコードを書いておきました。
もし、アドバイス等ありましたらよろしくお願いします。

お礼日時:2002/01/23 10:46

修飾子 g (処理の対象を全域にする)を使ってください。


if($buf !~ /(?:\x8E[\xA6-\xDF])/g){
とします。

正規表現には修飾子の他量指定子、位置指定子など、
色々ありますので、一度ネットや本で調べると面白いです。

私も、正規表現では苦労しています。頑張りましょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
上の記事に考えてみたコードを書いておきました。
また、おかしいところ等あればアドバイスよろしくお願いします。

正規表現は難しいですね。
でも、面白いものだとも思います。
がんばりたいと思いますでこれからもよろしくお願いします。

お礼日時:2002/01/23 10:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!