「数値以外除去」でやりたいことをイメージする
まず、ゴールのイメージからはっきりさせます。
"1,234" → "1234"
"¥9,800円" → "9800"
"TEL: 03-1234-5678" → "0312345678"
"123-456" → "123456"
やりたいことはシンプルです。
文字列の中から「数字だけ」を取り出したい。
数字以外の文字は全部いらないから、きれいに削ぎ落としたい。
これが「数値以外除去」です。
電話番号、郵便番号、金額、会員番号…
業務システムで「数字を含む文字列」を扱う場面では、ほぼ必ず出てきます。
ポイントは、「いきなり数値にキャストする」のではなく、
まず「文字列として数字だけを残す」というステップを用意することです。
一番の基本:正規表現で「数字以外」を全部消す
preg_replace で「いらないものを空文字にする」
PHP で「特定の条件に合う文字だけを残す/消す」ときの定番は、preg_replace です。
「数字以外を全部消す」は、こう書けます。
/**
* 数字以外の文字をすべて削除して、「数字だけの文字列」にする
*/
function onlyDigits(string $value): string
{
return preg_replace('/[^0-9]/', '', $value);
}
PHPここでのパターン /[^0-9]/ を分解すると、
[0-9]は「0〜9 のどれか1文字」[^0-9]は「0〜9 以外の1文字」- それを
''(空文字)に置き換える → 「数字以外を全部消す」
という意味になります。
例で動きを確認する
echo onlyDigits("1,234"); // 1234
echo onlyDigits("¥9,800円"); // 9800
echo onlyDigits("TEL: 03-1234-5678"); // 0312345678
echo onlyDigits("abc"); // (空文字)
PHP「数字以外は全部いらない」という割り切りなので、
記号・文字・スペースなどはきれいさっぱり消えます。
ここが「数値以外除去」の一番シンプルで強力な形です。
全角数字もちゃんと扱いたい場合
日本語入力だと「全角数字」が混ざる
フォーム入力などでは、ユーザーが全角で数字を入れてくることがあります。
"12345"
"123-456"
さっきの onlyDigits() にそのまま渡すと、
全角数字は「0〜9 ではない」ので、全部消えてしまいます。
echo onlyDigits("12345"); // (空文字)
PHPこれでは困るので、「全角数字を半角に変換してから、数字以外を消す」という二段構えにします。
mb_convert_kana で全角数字 → 半角数字
/**
* 全角数字も含めて、「数字だけの文字列」にする
*/
function onlyDigitsWithZenkaku(string $value): string
{
// 全角数字を半角に変換
$value = mb_convert_kana($value, 'n', 'UTF-8');
// 数字以外を削除
return preg_replace('/[^0-9]/', '', $value);
}
PHPmb_convert_kana($value, 'n', 'UTF-8') の 'n' は「全角数字を半角に」という指定です。
これで、次のように動きます。
echo onlyDigitsWithZenkaku("12345"); // 12345
echo onlyDigitsWithZenkaku("123-456"); // 123456
echo onlyDigitsWithZenkaku("TEL:03−1234−5678"); // 0312345678
PHP日本語環境の業務システムなら、
「全角数字を半角にしてから数字以外を消す」は、ほぼ必須パターンです。
「数値に変換する」ときは一歩だけ先に進む
「数字だけの文字列」から「数値」へ
onlyDigits() や onlyDigitsWithZenkaku() は、
あくまで「文字列としての数字」を返します。
金額や数量として計算したいときは、
そこからさらに「数値」に変換します。
$raw = "¥9,800円";
$digits = onlyDigitsWithZenkaku($raw); // "9800"
$amount = (int)$digits; // 9800(整数)
var_dump($amount); // int(9800)
PHPここでの大事な考え方は、
- まず「文字列としての数字だけ」にする
- そのあとで「数値」にキャストする
という二段階に分けることです。
いきなり (int)"¥9,800円" のようにキャストすると、
PHP は先頭から見て「数字じゃない」と判断した時点で 0 にしてしまうので、
意図しない結果になりがちです。
よくある実務シナリオでの使い方
フォーム入力の金額を正規化する
ユーザーが金額を入力するフォームを考えます。
$_POST['amount'] = "¥12,345円";
PHPこれを「DB に保存する数値」として扱いたいときの流れは、こうなります。
$raw = $_POST['amount'] ?? '';
$digits = onlyDigitsWithZenkaku($raw); // "12345"
$amount = (int)$digits; // 12345
// $amount を DB に保存する
PHP保存するときは「数値」または「数字だけの文字列」にしておき、
表示するときに number_format や通貨記号付きフォーマットを使う、
という設計にすると、金額周りの処理がとても安定します。
電話番号・郵便番号の正規化にもそのまま使える
電話番号や郵便番号のときも、
最初のステップは「数字だけにする」でした。
function normalizePhoneDigits(string $phone): string
{
return onlyDigitsWithZenkaku($phone);
}
function normalizeZipDigits(string $zip): string
{
return onlyDigitsWithZenkaku($zip);
}
PHPこうしておけば、
- 電話番号のフォーマット
- 郵便番号のフォーマット
など、後続の処理は「数字だけの文字列」を前提に書けます。
設計として大事なことを少し深掘りする
「入力のゆらぎ」を一箇所で吸収する
ユーザー入力や外部システムからのデータは、
必ず「ゆらぎ」があります。
- カンマ付きだったり、なかったり
- 全角だったり、半角だったり
- 通貨記号や単位が付いていたり
これを、アプリケーションのあちこちで個別に対処し始めると、
すぐにカオスになります。
そこで、
「数字を扱う前に、必ず
onlyDigitsWithZenkaku()を通す」
というルールを決めてしまうと、
「入力のゆらぎ」を一箇所で吸収できるようになります。
その結果、
- バリデーションが書きやすくなる
- DB の中身がきれいにそろう
- バグの原因が減る
という、地味だけど効き目の大きいメリットが出てきます。
まとめ:今日からの「数値以外除去」ユーティリティ
大事なところだけ、ぎゅっとまとめます。
「数値以外除去」は、
- 正規表現
preg_replace('/[^0-9]/', '', $value)で「数字以外を全部消す」 - 日本語環境では、
mb_convert_kana(..., 'n', ...)で全角数字を半角にしてからやる - 「数字だけの文字列」にしてから
(int)や(float)で数値に変換する - 金額・電話番号・郵便番号など、「数字を含む文字列」を扱う前処理として使う
核になるコードは、この2つです。
function onlyDigits(string $value): string
{
return preg_replace('/[^0-9]/', '', $value);
}
function onlyDigitsWithZenkaku(string $value): string
{
$value = mb_convert_kana($value, 'n', 'UTF-8');
return preg_replace('/[^0-9]/', '', $value);
}
PHP