TOP ▲ itcore TOP プログラムパーツ

uStrConvNFD NFD形式をNFC形式に変換する。 | itcore 2021年

PHP

PHP TOP

関数

<?php
function uStrConvNFD($strNFD) {
  //濁点の変換表
  $conv1 = array(
    'か' => 'が','き' => 'ぎ','く' => 'ぐ','け' => 'げ','こ' => 'ご',
    'さ' => 'ざ','し' => 'じ','す' => 'ず','せ' => 'ぜ','そ' => 'ぞ',
    'た' => 'だ','ち' => 'ぢ','つ' => 'づ','て' => 'で','と' => 'ど',
    'は' => 'ば','ひ' => 'び','ふ' => 'ぶ','へ' => 'べ','ほ' => 'ぼ',
    'ゝ' => 'ゞ',
    'カ' => 'ガ','キ' => 'ギ','ク' => 'グ','ケ' => 'ゲ','コ' => 'ゴ',
    'サ' => 'ザ','シ' => 'ジ','ス' => 'ズ','セ' => 'ゼ','ソ' => 'ゾ',
    'タ' => 'ダ','チ' => 'ヂ','ツ' => 'ヅ','テ' => 'デ','ト' => 'ド',
    'ハ' => 'バ','ヒ' => 'ビ','フ' => 'ブ','ヘ' => 'ベ','ホ' => 'ボ',
    'ウ' => 'ヴ','ヽ' => 'ヾ',
  );
  //濁点の変換表
  $conv2 = array(
    'は' => 'ぱ','ひ' => 'ぴ','ふ' => 'ぷ','へ' => 'ぺ','ほ' => 'ぽ',
    'ハ' => 'パ','ヒ' => 'ピ','フ' => 'プ','ヘ' => 'ペ','ホ' => 'ポ',
  );

  // 1文字づつ変換する。
  $strNFC = $c1 = $c1_pre = "";
  $len = mb_strlen($strNFD, 'UTF-8');
   for ($i = 0; $i <= $len; $i++) {
     $c1_pre = $c1;  // 1つ前の文字
     $c1 = mb_substr($strNFD, $i, 1, 'UTF-8');
     // Macの濁点
     if ($c1 == u_hex2bin('e38299')) {
       if (isset($conv1[$c1_pre])) {
         $strNFC .= $conv1[$c1_pre];
         $c1= "";
       } else {
         // 変換できないとき
         $strNFC .=  $c1_pre;
         $strNFC .=  u_hex2bin('e3829b'); // Windowsの全角濁点
       }
     // Macの半濁点
     } elseif ($c1 == u_hex2bin('e3829a')) {
       if (isset($conv2[$c1_pre])) {
         $strNFC .= $conv2[$c1_pre];
         $c1= "";
       } else {
         // 変換できないとき
         $strNFC .=  $c1_pre;
         $strNFC .=  u_hex2bin('e3829c'); // Windowsの全角半濁点
       }
     // 普通の文字
     } else {
         $strNFC .=  $c1_pre;
     }
   }
  return $strNFC;
}
?>

テストプログラム

<?php include_once "uStrConvNFD.func"; ?>
<?php include_once "u_hex2bin.func"; ?>
<?php
  $a = "データ";  // NFD
  $b = "データ";  // NFC
  echo 'strlen($a)='.strlen($a)."<br>\n";
  echo 'strlen($b)='.strlen($b)."<br>\n";
  $a = uStrConvNFD($a);
  echo 'strlen($a)='.strlen($a)."<br>\n";
?>

実行結果

strlen($a)=12
strlen($b)=9
strlen($a)=9