見出し画像

Byte計算でバリデーションをしてみた

初めましてblueです。

現在、ITベンチャー企業でWEB系システムの開発を行なっています。

今回担当する案件で、byte計算でバリデーションをかける必要がありました。その時に書いたコードをメモとして、残しておきます。

前提条件

全角文字については、前後に1byteずつ入れる。
半角文字は1byteで計算。全角文字は2byteで計算
全角スペース・半角スペースも扱いは同様。
30byte以内に納める

例:「あ2」
1byte + 全角文字2byte + 1byte + 半角文字1byte

例:「ああ2」
1byte + 全角文字4byte(2文字分)+ 1byte + 半角文字1byte

書いたコード

<?php

$count = 0;
$str_count = mb_strlen($value);

for ($i = 0; $i < $str_count; $i++) {
    if(preg_match("/^[^-a-zA-Z0-9ヲ-゚ ]+/u", $value, $match)) {
        $value = preg_replace("/^[^-a-zA-Z0-9ヲ-゚ ]+/u", "", $value);
        $count += strlen(mb_convert_encoding($match[0], 'SJIS', 'UTF-8')) + 2;
    } elseif (preg_match("/^[-a-zA-Z0-9ヲ-゚ ]+/u", $value, $match)) {
        $value = preg_replace("/^[-a-zA-Z0-9ヲ-゚ ]+/u", "", $value);
        $count += strlen(mb_convert_encoding($match[0], 'SJIS', 'UTF-8'));
    }
    $str_count = mb_strlen($value);
}

if($count <= 30)return true;

考え方

1. 正規表現で全角か半角か判断
2. マッチした正規表現の文字数を消す
3. マッチした正規表現が全角の場合、 +2バイト追加
4. 半角の場合は、文字数のバイトのみカウント
5. カウントを足していく
6. 30バイト以上の場合はバリデーションがかかる

コード説明

$valueの中に、入力された文字が入っています。

preg_match("/^[^-a-zA-Z0-9ヲ-゚ ]+/u", $value, $match)

正規表現で半角・全角を判定しています。
preg_match: 正規表現によるマッチングを行う

preg_replace("/^[^-a-zA-Z0-9ヲ-゚ ]+/u", "", $value);

preg_replace:正規表現検索および置換を行う

正規表現でマッチングした$valueの文字を置き換えて、byte計算した文字を除外しています。

strlen(mb_convert_encoding($match[0], 'SJIS', 'UTF-8')) + 2;

strlen:バイト数を返す
mb_strlen:文字列の長さを返す。(全角・半角ともに1文字として返されます。)

https://www.php.net/manual/ja/function.strlen.php

mb_convert_encodingで文字コードを変換しています。

UTF-8だと、全角を3byteとしてカウントしてしまうため、SJISに変換。

以上です。
もうちょっとまとめられると思いますが、リファクタリングはまた今度にします(笑)

やる前は悩んでいたけど、出来てみたら以外やれると感じました(笑)


いいなと思ったら応援しよう!

blue
良かったらサポートしていただけると嬉しいです!