文字列が日本語かどうか調べる方法について - PHPプロ!Q&A掲示板

1098

  • 0P

文字列が日本語かどうか調べる方法について

質問日時 / 2008年4月9日 10:07    回答数 / 7件

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

キーワード / 日本語    調べる    文字列   

初めて利用します。よろしくお願いします。

PHPでフォームの値で名前を受け取るときに、日本語かどうかをチェックしたいのですが、以下のように記述する方法しか知らなくて、大丈夫だと思っていたところ、日本語漢字「田」(田んぼの田です)を入力したときに、うまく判定できないのです。(たとえば、石田太郎、と名前をいれると日本語と判定してほしいところうまくいきません。PCからチェックしたところ、他の文字でもダメな場合もあり、カタカナだとさっぱりうまくいきません。)

根本的に間違っているんだと思います…。HTMLタグや改行文字の置換えをする関数も間に入れているので、自分で原因を探るのにがんばってみたのですが…。

何分、勉強しはじめたところで、解決法が見つけれなくて困っています。

どなたか教えていただけないでしょうか?


  1. <?php
  2. $name = $_REQUEST['name'];//名前を受け取る
  3.  
  4. //名前の文字をCSVに保存するため整形する関数
  5. function mojifilter(&$str){
  6. $str = str_replace(",""" ,$str);
  7. $str = nl2br($str);
  8. $str = str_replace("\n"""$str);
  9. $str = str_replace("\r"""$str);
  10. $str = stripslashes($str);
  11. $str = mb_convert_kana($str,"KVas","Shift_jis");
  12. $str = htmlspecialchars($str,ENT_QUOTES);
  13. return $str;
  14. }
  15.  
  16. mojifilter($name);
  17.  
  18. //英数字が使われていたらエラーメッセージ
  19. if(preg_match("/[0-9a-zA-Z]/"$name) == 1){
  20.   $check = FALSE;
  21.   $error = "お名前に英数字は使えません。";
  22. }
  23. ?>

よろしくお願いします。

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



ツリー一覧

┣A01atsushiものすごーーくおおざっぱな判定でよければ、自分はst
┃┗A01-1airutonatsushiさん、ありがとうございます。 そのように
┣A02TorrySegallpreg系関数がマルチバイトに対応していないからです。
┃┣A02-1weekendphpTorrySegallさんがおっしゃってるように、pregでは日
┃┃┗A02-1-1airutonweekendphpさん、ありがとうございます。 weekendp
┃┣A02-2airutonこの意見は質問者によって削除されました。
┃┗A02-3airutonTorrySegallさん、ありがとうございます。 間違いの
┗A03airutonなにやらお礼の書き込みの順序、場所が変になってしま

回答一覧

並び替え:

A01 参考になった
answereratsushi [4月9日 21:08]

ものすごーーくおおざっぱな判定でよければ、自分はstrlenmb_strlenを使って判定しています。
  1. if (strlen($text) == mb_strlen($text)) {
  2.   // $textは全部英語(全部シングルバイト文字)
  3. } else {
  4.   // $textには日本語が含まれている(マルチバイト文字が含まれている)
  5. }

日本語を見分けるというよりは、テキストにマルチバイト文字が入っているかどうかを見分ける処理です。
厳密さを求めないシステムならばそこそこ使えると思います。

ただ、↓のリンクにあるようにmb_strlenは条件によっては値が変わることがあるらしいので注意してください。
http://www.phppro.jp/phptips/archives/vol8/2

この意見に回答する

ツリーへ TOPへ

A01-1
replyerairuton [4月10日 15:55]

atsushiさん、ありがとうございます。

そのように文字数に置換え、比較するという手もあるんですね!
大変勉強になりました。

この意見に回答する

ツリーへ TOPへ

A02 参考になった
answererTorrySegall [4月10日 04:34] (最終編集:4月10日 04:44)

preg系関数がマルチバイトに対応していないからです。

Shift_JISであれば、0x93, 0x63 というバイトの連なりで "田" という文字が表現されますが
この2バイト目の 0x63 は、それ1バイトでは英数字である "c" を表現してしまいます。
preg系の関数は文字コードを全く問題にせず、バイナリ値だけで文字列を処理するので
"c" を preg_match で検索すれば『"田" の2バイト目』もHITしてしまう...と。

この意見に回答する

ツリーへ TOPへ

A02-1 満足
replyerweekendphp [4月10日 15:58]

TorrySegallさんがおっしゃってるように、pregでは日本語(マルチバイト文字)に対応していないので、
そのような誤判定が起こります。

なので、mb_eregなどのマルチバイト対応関数を利用すれば、大丈夫だと。

  1. //英数字が使われていたらエラーメッセージ
  2. mb_regex_encoding("Shift_jis");
  3. if(mb_ereg("[0-9a-zA-Z]", $name) == 1){
  4.   $check = FALSE;
  5.   $error = "お名前に英数字は使えません。";
  6. }

参考まで。

この意見に回答する

ツリーへ TOPへ

A02-1-1
replyerairuton [4月10日 16:11]

weekendphpさん、ありがとうございます。

weekendphpさんのコードでばっちり期待した結果が得られました。

mb_ereg関数と同時に、mb_regex_encodingで内部で正規表現に対するエンコードも指定いないとダメなんですね。

携帯用ということで内部はSJIS、PHPの設定はeuc-jpのままだったので、mb_regex_encodingを指定することの必要性も大変勉強になりました。

この意見に回答する

ツリーへ TOPへ

A02-2
replyerairuton [4月10日 16:00]

この意見は質問者によって削除されました。

ツリーへ TOPへ

A02-3
replyerairuton [4月10日 16:03]

TorrySegallさん、ありがとうございます。
間違いの原因をわかりやすく教えていただき、すっきりしました。

マルチバイト文字列関数をもっと調べていろいろ試してみたいと思います。

この意見に回答する

ツリーへ TOPへ

A03
answererairuton [4月10日 16:14]

なにやらお礼の書き込みの順序、場所が変になってしまいましたが^^;

みなさんのおかげで、大変勉強になり、無事、期待した結果を得ることもできました。

あらためてありがとうございました!!

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
ログファイルの中の空のデータ行を削除したい
 このエントリーをはてなブックマークに追加 
A
ログのデータ個数(列数)が固定で、空のログが"<><><>"だと既知であれば if ($line === "<><><>") { continue; } で読み飛ばしてもいいのでは? ...

>>続きを読む

まずは配列や文字列の扱いから、じっくり勉強して行きましょう。

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