フォームでの文字列チェックに関して質問があります。 - PHPプロ!Q&A掲示板

1210

  • 0P

フォームでの文字列チェックに関して質問があります。

質問日時 / 2008年6月5日 09:37 (最終編集:6月5日 15:46)    回答数 / 11件

Questioner:  moana  このエントリーをはてなブックマークに追加 

キーワード / フォーム    文字列    機種依存文字チェック   

PHPでの文字列チェックについて質問があります。 

PHPでの文字列チェックについて教えてください。 

PHPで文字列のチェックを行っているのですがどうも思うように
結果が出ません。

現在の処理は、

$ck = "/^[\x87][\x3F-\x9E]/";//機種依存文字チェック
$ck1= "^[0-9]+$"; //数字チェック用

if (preg_match($ck,$message)) { 
$msg = "機種依存文字が存在します!";
}

if (preg_match($ck1,$message)) { 
$msg = "数字がが存在します!";
}

このような感じになっております。

$message = "㈱";

こちらの場合は$msgが出力されます。

$message = "ああああああ㈱";

こちらの場合、$msgが出力されません。

同じく

$message = "0000"; $msgが出ます。
$message = "6月30日"; $msgが出ません。

機種依存文字はSJISの13区画の文字を対象としています。

上記のいずれの場合でも$msgを出力するにはどのようにすればよいでしょうか?

よろしくお願いいたします。

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01mgngmgng>>CODE $ck = "/[\x87][\x3F-\x9E]/"; $ck1= "/[0-9
┃┗A01-1moana ありがとうございます。 上記の設定で機種依存文
┃ ┗A01-1-1mgngmgngうーん、こちらの環境ではちゃんとメッセージが出力さ
┃  ┗A01-1-1-1moana ご連絡ありがとうございます。 すいません。ちょっ
┃   ┗A01-1-1-1-1mgngmgngじゃこれですね。 $ck1= "/^[0-9]+$/"; 「文字
┃    ┗A01-1-1-1-1-1moana 解決致しました。 ctype_digit というチェック
┗A02kaitau落ち着いたところで問題提起を一つ。 実は、Shift_
 ┗A02-1mgngmgng確かにそうですね。ごもっともです... 後先あまり
  ┗A02-1-1moanaあ!その文字がだめになってしまうのですね。。。 2
   ┗A02-1-1-1kaitauむしろ文字コードへの理解が間違っているかと。 Sh
    ┗A02-1-1-1-1moana なるほどですね。。。 今回S-jisにこだわってい

回答一覧

並び替え:

A01 満足
answerermgngmgng [6月5日 12:56]

  1. $ck = "/[\x87][\x3F-\x9E]/";
  2. $ck1= "/[0-9]/";

この意見に回答する

ツリーへ TOPへ

A01-1
replyermoana [6月5日 14:08]


ありがとうございます。

上記の設定で機種依存文字は解決しましたが、
どうも数字の方が解決できません。

引き続き数字チェックの部分に関して情報がありましたら
教えて頂ければと思います。

以上何卒よろしくお願い致します。

この意見に回答する

ツリーへ TOPへ

A01-1-1
replyermgngmgng [6月5日 14:39]

うーん、こちらの環境ではちゃんとメッセージが出力されるんですけどねー...
  1. <?php
  2. $ck1"/[0-9]/";
  3.  
  4. $message = "0000";
  5. if (preg_match($ck1,$message)) {
  6.   echo 'error1';
  7. }
  8.  
  9. $message = "6月30日";
  10. if (preg_match($ck1,$message)) {
  11.   echo 'error2';
  12. }

この意見に回答する

ツリーへ TOPへ

A01-1-1-1
replyermoana [6月5日 14:44]


ご連絡ありがとうございます。
すいません。ちょっとこちらの質問が間違っていました。

数字のみの場合はOKとし数字以外の時はNGという
処理を行いたいと思っております。

ですので、

111 -> OK
a11 -> NG
1a1  -> NG

といった感じとなります。質問内容が間違っておりまして
誠に申し訳ございません。

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1 満足
replyermgngmgng [6月5日 15:43]

じゃこれですね。

$ck1= "/^[0-9]+$/";

「文字列が数字だけで構成されていればOK」
チェックであれば ctype_digit が簡単でいいと思います。

  1. <?php
  2. ctype_digit('111');  // true
  3. ctype_digit('a11');  // false
  4. ctype_digit('1a1');  // false
  5. ctype_digit('-10');  // false
  6. ctype_digit('99.9')// false
  7. ctype_digit(111);    // false ※文字列じゃないのでfalseです

この意見に回答する

ツリーへ TOPへ

A01-1-1-1-1-1
replyermoana [6月5日 15:46]



解決致しました。

ctype_digit というチェックもあるのですね。
とても勉強になりました。

いろいろと対応して頂きましてありがとうございました。

この意見に回答する

ツリーへ TOPへ

A02
answererkaitau [6月5日 16:14]

落ち着いたところで問題提起を一つ。

実は、Shift_JISの文字列から2バイト分だけ取り出して判定するというのは、
あまり正確でないでないので、時として問題を起こす可能性があります。
PHPという言語に限らず、そして正規表現という手法に限らず。

例えば、preg_matchでの
/[\x87][\x3F-\x9E]/
のパターンだと、

検査する文字列が
「順位」とか
「応援@甲子園」などの
場合に
機種依存文字が存在します!
と言われてしまうと思います。
(構築しているシステムで想定している文字列かは置いておいて)

この現象は、トレーラーバイトが x87 の文字の次にx3F-x9Eの
範囲をもつリーダーバイトの2バイト文字なり1バイト文字なりの
文字列で起こりえます。

私は、結局mb_substrを駆使して一文字ずつ検査する位しか回避策を
見出していないのですが・・・。

この意見に回答する

ツリーへ TOPへ

A02-1
replyermgngmgng [6月5日 17:34]

確かにそうですね。ごもっともです...

後先あまり考えなければこんな感じでもいいのかもしれないですが
  1. <?php
  2. function check($s) {
  3.   $f = 'SJIS';
  4.   $t = 'UTF-8';
  5.   $c = mb_convert_encoding(mb_convert_encoding($s,$t,$f),$f,$t);
  6.   return (strcmp($s,$c)===0);
  7. }
  8.  
  9. var_dump(
  10.   check('順位'),        // true
  11.   check('応援@甲子園')// true
  12.   check('ほげほげ①'),  // false
  13.   check('㈱あああ'),    // false
  14.   check('ⅠⅡⅢ')       // false
  15. );

この意見に回答する

ツリーへ TOPへ

A02-1-1
replyermoana [6月5日 18:49]

あ!その文字がだめになってしまうのですね。。。
2バイト文字はなかなかやっかいです。。

すいません。ついでに質問ついでなのですが、
全角かどうかをチェックする場合、

下記で行ってしまうと漢字がエラーになってしまいます。
そもそも文字コード指定が違うのでしょうか?


  1. $ck="/^[\x80-\xFF]+$/";
  2.  
  3. if (!preg_match($ck,$message)) {
  4.  $msg = "全角文字でありません!";
  5. }

この意見に回答する

ツリーへ TOPへ

A02-1-1-1
replyerkaitau [6月5日 20:49]

むしろ文字コードへの理解が間違っているかと。

Shift_JISでは、トレーラーバイトが0x40-0x7fの領域に割り当てられている
文字も存在します。
例えば、「外」とか「角」とか。

こういった文字の場合、
「0x80から0xFFまでだよ」というパターンの正規表現では、範囲外
と認識されてしまいます。Shift_JISの場合は。

余談かもしれませんが、いわゆる半角カタカナのみの文字列を「全角文字でありません!」と
出したくても、上記のパターンだと逆にOKになってしまいますね。

といった按配で、正規表現でShift_JISの全角判定をやろうとすると、
パターンが結構複雑になりそうなので、私の場合は文字列にmb_convert_kana
をかまして半角全角の変換を行い、変換前の文字列と変換後の文字列のバイト数を
比較して、違ったら半角文字が混じっていただろう、と判定することにしています。

そもそも、Shift_JISをあまり使わないほうが良いって話もあります。
特殊な制限がかかる携帯コンテンツで無い限りは。

この意見に回答する

ツリーへ TOPへ

A02-1-1-1-1
replyermoana [6月5日 21:00]



なるほどですね。。。
今回S-jisにこだわっているのはS-jisの環境での
チェックでしたので。。。。

一応、上記ではない方法で実現はできました。
ただ、2バイト文字の取り扱いはなかなか大変だと実感しました。

いろいろとありがとうございました。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
負荷時のmysql_connect()エラー
 このエントリーをはてなブックマークに追加 
A
これはPHPというよりOSまたはMySQLのコミュニティで質問されたほうがいいと思います。 ぱっと思いついた範囲で記すと MySQL等のDBに「ある時点において同時に接続可能なクライアントの最大数」に制限があるよう...

>>続きを読む

今回のような実践的な経験がエンジニアのキャリアに繋がると思います。是非サービスを成功させて下さい!

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)