PHP での半角文字チェックはこれでいいんじゃないの

ある文字列が半角のみでできていること、
つまり全角文字が含まれていないこと、
を確認したいことがたまにある。

そのやり方としていろんな人がいろんなことを書いていて
正規表現を使うものが多いと思うんだけど、
こんなんでもいいんじゃないかな。

1
2
3
4
5
if (strlen($str) === mb_strlen($str)) {
    return true;
} else {
    return false;
}

シングルバイト扱いでの長さとマルチバイト扱いでの長さが同じなら半角。

これに文字エンコーディングの指定や半角カナ、制御文字の扱いを含めたら
こんな感じでしょうか。

<?php
function is_hankaku($str, $include_kana = false, $include_controls = false, $encoding = null) {
if (!$include_controls && !ctype_print($str)) {
return false;
}
if (is_null($encoding)) {
$encoding = mb_internal_encoding();
}
if ($include_kana) {
$to_encoding = 'SJIS';
} else {
$to_encoding = 'UTF-8';
}
$str = mb_convert_encoding($str, $to_encoding, $encoding);
if (strlen($str) === mb_strlen($str, $to_encoding)) {
return true;
} else {
return false;
}
}
view raw is_hankaku.php hosted with ❤ by GitHub

  • 半角カナを許可するなら $include_kanatrue に。デフォルト値は false.
  • 改行やタブなども許可するなら $include_controlstrue に。デフォルト値は false.
  • 入力文字列 $str の文字エンコーディングを $encoging で指定。省略したら PHP の内部文字エンコーディングが使われます。

半角カナを含める場合は与えられた文字列を Shift_JIS に変換してから、
含めない場合は UTF-8 にしてから判定します。
半角カナは Shift_JIS ではシングルバイト、
UTF-8 ではマルチバイトなので。

制御文字の排除には ctype_print() を使っています。

PHP: ctype_print – Manual

text に制御文字 またはまったく出力も制御も行わない文字が含まれる場合に FALSE を返します。

ざっと検索してみたら見当たらなかったので書いてみたんだけど
「それ常套手段だよ」とか「それじゃダメだよ」とか
「そんなことしなくてもいいのに」とかあったら教えてください。

2 Responses to “PHP での半角文字チェックはこれでいいんじゃないの”

  • a

    2012/03/23 20:25

    まずいケース?
    http://ideone.com/A5BGN

  • あきら

    2012/03/24 02:23

    mb_strlenとmb_strwidthを使ったほうがいいと思います
    マルチバイトをstrlenで数えるのはちょっと気持ち悪いかもしれません
    strlenの中身がmb_strlenになっている環境もたまにあるので。。。

    大抵の場合にはmb_strlen===mb_strwidthで半角で
    mb_strlen*2===mb_strwidthで全角でも問題はない気がします

:)