えせ Normalize (Re:青空迷子)

小生、不勉強にて iconv に //TRANSLIT や //IGNORE という機能があることをずっと知りませんでした。PHP マニュアル - iconv() にもばっちり書いてあったのに。
で、説明はリンク先や iconv_open(3) の man ページにあるので省きますが、これはすごく便利ですね。これを使って先日の NFC 正規化関数を書き直してみました。Yet-Another というよりは Would-be のほうが妥当な気がしないでもない、似非 NFKC 関数です。

<?php
// Yet-Another/Would-be Normalization Form K(C)ompatibility Composition

function YANFKC($str, $extra = false)
{
    $str = preg_replace_callback('/([うか-こさ-そた-とは-ほウカ-コサ-ソタ-トハ-ホゝヽ])\\x{3099}|([は-ほハ-ホ])\\x{309A}/u', '_YANFKC', $str);
    $enc = ($extra) ? 'CP932' : 'SJIS';
    return iconv($enc, 'UTF-8', iconv('UTF-8', $enc . '//TRANSLIT//IGNORE', $str));
}

function _YANFKC($m)
{
    $i = ($m[1]) ? 1 : 2;
    $C = unpack('C*', $m[$i]);
    return pack('C*', $C[1], $C[2], $C[3] + $i);
}

exec('ls ' . escapeshellarg(getenv('HOME') . '/Documents'), $D);
$D[] = base64_decode('442Kw6Tih4zikaDikpzihKs=');

foreach ($D as $L) {
    $l = YANFKC($L, !empty($argv[1]));
    if ($L != $l) {
        var_dump($L, $l);
    }
}

?>

C 言語が書けず、Unicode の仕様書とにらめっこする根性のない小生にはこれが精一杯です。C ができれば ICU 使って適当な拡張モジュールをでっち上げるところなんですが。Perl/Python/Ruby ならそのものズバリのメソッドがあるのには目を瞑ろう。