PHP で平仮名(ひらがな)のバリデーションを作る

目次

結論

簡易的には、PCRE 関数 の preg_match を利用して正規表現のマッチングによるバリデーションを実装します。

第一引数の pattern には、PCRE 正規表現構文Unicode 文字プロパティ である\p{Hiragana}(U+30FC) を指定します。

function checkHiragana(string $str): int|false {
  return preg_match("/\A[\p{Hiragana}ー]+\z/u", $str);
}

マッチする範囲は下記になります。

  1. (U+3041) –(U+309F) : Hiragana
  2. U+1B001 – U+1B0FF : Kana Supplement
  3. U+1B100 – U+1B11F : Kana Extended-A
  4. U+1B150 – U+1B152 : Small Kana Extension
  5. U+1F200 : Enclosed Ideographic Supplement
  6. (U+30FC) : Katakana

uを記述しないと (U+3080) とマッチしないことがあるのでご注意下さい。

文字で範囲を指定する場合、例えば、Hiragana +(U+30FC) は下記のようになります。

function checkHiragana(string $str): int|false {
  return preg_match("/\A[ぁ-ゟー]+\z/u", $str);
}

マッチする範囲は下記になります。

  1. (U+3041) –(U+309F) : Hiragana
  2. (U+30FC) : Katakana

pattern は要件に合わせて、柔軟に書き換えて対応すれば良いでしょう。

環境

  1. MAMP 6.8
  2. Apache 2.4.54
  3. PHP 8.2.0

解説

初めに、Unicode Block を理解する必要があります。

Unicode とは、簡単に言うと Unicode Consortium という非営利団体によって維持されている世界中の文字や記号を 1 つの文字コード体系で扱える様に作られた符号化文字集合のことです。

Unicode Block とは、Code point の連続する範囲のことです。

Code point とは、特定の文字にマップされる数値のことです。

例えば、Unicode は 0 hex – 10FFFF hex の数値です。

仕様

平仮名の Unicode Block は、下表の通り U+3040 〜 U+309F の 96 個(内 3 個の保留)になります。

0123456789BCDEF
U+304x
U+305x
U+306x
U+307x
U+308x
U+309x
Hiragana(Unicode 15.1)

実装

PCRE 関数 の preg_match を利用して正規表現のマッチングによるバリデーションを実装します。

第一引数の pattern には、PCRE 正規表現構文 の Unicode 文字プロパティ である\p{Hiragana}(U+30FC) を指定します。

function checkHiragana(string $str): int|false {
  return preg_match("/\A[\p{Hiragana}ー]+\z/u", $str);
}

記述している PCRE 正規表現構文 の説明になります。

  1. /: デリミタ
  2. \A: エスケープシーケンス 検索対象文字列の始端
  3. []文字クラス
  4. \p{Hiragana} : マッチする範囲は下記になります。
    1. (U+3041) –(U+309F) : Hiragana
    2. U+1B001 – U+1B0FF : Kana Supplement
    3. U+1B100 – U+1B11F : Kana Extended-A
    4. U+1B150 – U+1B152 : Small Kana Extension
    5. U+1F200 : Enclosed Ideographic Supplement
  5. : Katakana
  6. +: 量指定子 {1,} と同じ 直前の表現を 1 回以上繰り返す
  7. \z: エスケープシーケンス 検索対象文字列の終端
  8. u: 修飾子 UTF-8 として処理する

u が無いと(U+3080) とマッチしないことがあることにご注意下さい。

文字で範囲を指定する場合、例えば、Hiragana +(U+30FC) は下記のようになります。

function checkHiragana(string $str): int|false {
  return preg_match("/\A[ぁ-ゟー]+\z/u", $str);
}

記述している PCRE 正規表現構文 の説明になります。

  1. /: デリミタ
  2. \A: エスケープシーケンス 検索対象文字列の始端
  3. []文字クラス
  4. ぁ-ゟ: Hiragana
  5. : Katakana
  6. +: 量指定子 {1,} と同じ 直前の表現を 1 回以上繰り返す
  7. \z: エスケープシーケンス 検索対象文字列の終端
  8. u: 修飾子 UTF-8 として処理する

因みに、^[...]$という書き方は 修飾子 のmを指定している場合、改行の有無によって動作が変わるので、特別な事情が無い限りは動作が統一されている\A[...]\zを指定するのが無難と思われます。

$str = 'あい
うえお';

var_dump(preg_match("/\A[ぁ-ゟー]+\z/u", $str)); // マッチしない int(0)
var_dump(preg_match("/\A[ぁ-ゟー]+\z/mu", $str)); // マッチしない int(0)
var_dump(preg_match("/^[ぁ-ゟー]+$/u", $str)); // マッチしない int(0)
var_dump(preg_match("/^[ぁ-ゟー]+$/mu", $str)); // マッチする int(1)

pattern は要件に合わせて、柔軟に書き換えて対応すれば良いでしょう。

検証

検証用の簡単なプログラムを書きました。

<?php
$hiragana = $_POST['hiragana'] ?? '';
$hiragana_2 = $_POST['hiragana2'] ?? '';

if ($hiragana) {

  if (checkHiragana($hiragana)) echo '<p>pattern 1 : OK</p>';
  else echo '<p>pattern 1 : NG</p>';
}

if ($hiragana_2) {

  if (checkHiragana2($hiragana_2)) echo '<p>pattern 2 : OK</p>';
  else echo '<p>pattern 2 : NG</p>';
}

function checkHiragana(string $str): int|false {
  return preg_match("/\A[\p{Hiragana}ー]+\z/u", $str);
}

function checkHiragana2(string $str): int|false {
  return preg_match("/\A[ぁ-ゟー]+\z/u", $str);
}

?>

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>

<hr>
<form method="post">
  <p>
  平仮名(Unicode 文字プロパティ): <input type="text" name="hiragana">
  </p>
  <p>
  平仮名(正規表現): <input type="text" name="hiragana2">
  </p>
  <input type="submit" value="送信する">
</form>

</body>
</html>

平仮名(Unicode 文字プロパティ)

下記の文字列とマッチします。

ぁあぃいぅうぇえぉおかがきぎく
ぐけげこごさざしじすずせぜそぞた
だちぢっつづてでとどなにぬねのは
ばぱひびぴふぶぷへべぺほぼぽまみ
むめもゃやゅゆょよらりるれろゎわ
ゐゑをんゔゕゖ゛゜ゝゞゟー

平仮名(正規表現)

下記の文字列とマッチします。

ぁあぃいぅうぇえぉおかがきぎく
ぐけげこごさざしじすずせぜそぞた
だちぢっつづてでとどなにぬねのは
ばぱひびぴふぶぷへべぺほぼぽまみ
むめもゃやゅゆょよらりるれろゎわ
ゐゑをんゔゕゖ゛゜ゝゞゟー

参考

  1. PHP マニュアル
  2. Unicode block
目次