小生、不勉強にて 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 ならそのものズバリのメソッドがあるのには目を瞑ろう。