PHP 文字エンコード
PHP による日本語の文字コード判定スクリプト
文字列の文字コードを判定する場合、PHP には mb_detect_encoding() 関数が用意されていますが、文字列が短い場合、判定に失敗することが多くなりますので、もう少し判定率の良いスクリプトを作成してみました。
mbstring(マルチバイト文字列関数) と mbregex(マルチバイト正規表現関数) が必要です。文字コード範囲が重なるような場合は、SJIS-win を優先させています。
各文字コードの範囲については、Perl メモ:文字の正規表現を参考にしました。
/**
* 日本語文字列の文字コード判定(ASCII/JIS/eucJP-win/SJIS-win/UTF-8 のみ)
*/
function detect_encoding_ja( $str )
{
$enc = @mb_detect_encoding( $str, 'ASCII,JIS,eucJP-win,SJIS-win,UTF-8' );
switch ( $enc ) {
case FALSE :
case 'ASCII' :
case 'JIS' :
case 'UTF-8' : break;
case 'eucJP-win' :
// ここで eucJP-win を検出した場合、eucJP-win として判定
if ( @mb_detect_encoding( $str, 'SJIS-win,UTF-8,eucJP-win' ) === 'eucJP-win' ) {
break;
}
$_hint = "xbfxfd" . $str; // "xbfxfd" : EUC-JP "雀"
// EUC-JP -> UTF-8 変換時にマッピングが変更される文字を削除( ≒ ≡ ∫ など)
mb_regex_encoding( 'EUC-JP' );
$_hint = mb_ereg_replace( "xad(?:xe2|xf5|xf6|xf7|xfa|xfb|xfc|xf0|xf1|xf2)", '', $_hint );
$_tmp = mb_convert_encoding( $_hint, 'UTF-8', 'eucJP-win' );
$_tmp2 = mb_convert_encoding( $_tmp, 'eucJP-win', 'UTF-8' );
if ( $_tmp2 === $_hint ) {
// 例外処理( EUC-JP 以外と認識する範囲 )
if (
// SJIS と重なる範囲(2バイト|3バイト|iモード絵文字|1バイト文字)
! preg_match( '/^(?:'
. '[x8ExE0-xE9][x80-xFC]|xEA[x80-xA4]|'
. 'x8F[xB0-xEF][xE0-xEF][x40-x7F]|'
. 'xF8[x9F-xFC]|xF9[x40-x49x50-x52x55-x57x5B-x5Ex72-x7Ex80-xB0xB1-xFC]|'
. '[x00-x7E]'
. ')+$/', $str ) &&
// UTF-8 と重なる範囲(全角英数字|漢字|1バイト文字)
! preg_match( '/^(?:'
. 'xEFxBC[xA1-xBA]|[x00-x7E]|'
. '[xE4-xE9][x8E-x8FxA1-xBF][x8FxA0-xEF]|'
. '[x00-x7E]'
. ')+$/', $str )
) {
// 条件式の範囲に入らなかった場合は、eucJP-win として検出
break;
}
// 例外処理2(一部の頻度の多そうな熟語は eucJP-win として判定)
// (珈琲|琥珀|瑪瑙|癇癪|碼碯|耄碌|膀胱|蒟蒻|薔薇|蜻蛉)
if ( mb_ereg( '^(?:'
. 'xE0xDDxE0xEA|xE0xE8xE0xE1|xE0xF5xE0xEF|xE1xF2xE1xFB|'
. 'xE2xFBxE2xF5|xE6xCExE2xF1|xE7xAFxE6xF9|xE8xE7xE8xEA|'
. 'xE9xACxE9xAF|xE9xF1xE9xD9|[x00-x7E]'
. ')+$', $str )
) {
break;
}
}
default :
// ここで SJIS-win と判断された場合は、文字コードは SJIS-win として判定
$enc = @mb_detect_encoding( $str, 'UTF-8,SJIS-win' );
if ( $enc === 'SJIS-win' ) {
break;
}
// デフォルトとして SJIS-win を設定
$enc = 'SJIS-win';
$_hint = "xe9x9bx80" . $str; // "xe9x9bx80" : UTF-8 "雀"
// 変換時にマッピングが変更される文字を調整
mb_regex_encoding( 'UTF-8' );
$_hint = mb_ereg_replace( "xe3x80x9c", "xefxbdx9e", $_hint );
$_hint = mb_ereg_replace( "xe2x88x92", "xe3x83xbc", $_hint );
$_hint = mb_ereg_replace( "xe2x80x96", "xe2x88xa5", $_hint );
$_tmp = mb_convert_encoding( $_hint, 'SJIS-win', 'UTF-8' );
$_tmp2 = mb_convert_encoding( $_tmp, 'UTF-8', 'SJIS-win' );
if ( $_tmp2 === $_hint ) {
$enc = 'UTF-8';
}
// UTF-8 と SJIS 2文字が重なる範囲への対処(SJIS を優先)
if ( preg_match( '/^(?:[xE4-xE9][x80-xBF][x80-x9F][x00-x7F])+/', $str ) ) {
$enc = 'SJIS-win';
}
}
return $enc;
}
文字コード判定の考え方としては、以下のようになっています。
- EUC-JP -> UTF-8 への変換してから、UTF-8 -> EUC-JP を行った場合、逆変換に成功することは少ない
- まず、文字コードがあいまいな文字列を EUC-JP として検出させ、1. より、EUC-JP で無いことを確認した場合は SJIS か UTF-8 を判定
- EUC-JP での逆変換に成功した場合、SJIS と文字コードが重なる部分は SJIS を優先
- EUC-JP でない場合、UTF-8 と仮定して逆変換に成功した場合のみ UTF-8 として検出
- 例外は個別対応
この文字コード判定スクリプトには以下の問題があります。
- 少し重くなる
- PHP の mbstring に依存している(汎用性がない)
- EUC-JP のいわゆる半角カタカナ(\x8e[\xa1-\xfc])や、EUC-JP の一部の文字([\xe0-\xea][\xa1-\xfc])のみで 構成される文字列は SJIS-win として判定される
- UTF-8 の一部の記号(数学記号とギリシア文字の一部)が含まれる文字列が eucJP-win として判定される
使用方法としては、以下のように文字コードが分からない日本語文字列を UTF-8 に変換するような関数を作成する場合に便利です。
function convert_utf8( $str )
{
$encoding = detect_encoding_ja( $str );
return mb_convert_encoding( $str, 'UTF-8', $encoding );
}
トラックバック URL :
Young nymphets….
Nude nymphets. Little nymphets. Nymphets. Et-nymphets nudes. Ukrainian nymphets. Nym (more…)
トラックバック by Little nymphets. — 2008/11/17 月曜日 @ 7:45:53
Eternal nymphets….
Nymphets galleries. (more…)
トラックバック by Nude nymphets. — 2008/11/30 日曜日 @ 6:35:33
Dog sex stories….
Dog sex stories. Free sex dog mpeg. (more…)
トラックバック by Dog sex. — 2008/12/1 月曜日 @ 7:32:16
Free animal hardcore porn….
Zoo sex pictures animal porn movies beast trailers. Askjolene com animal porn sex. A (more…)
トラックバック by Horse sex girls beastiality animal sex porn pics. — 2008/12/2 火曜日 @ 7:36:40
Bestiality zoo animal sex hors…
Animal sex zoo free porn bestiality horse dog. Horse porn beast porn zoo. Horse porn (more…)
トラックバック by Zoo porn movies animal porn movies dog porn movies. — 2008/12/3 水曜日 @ 7:58:03
Buy amoxicillin without prescr…
Buy amoxicillin without prescription. (more…)
トラックバック by Buy amoxicillin without prescription. — 2008/12/7 日曜日 @ 6:50:06
Buy amoxicillin without prescr…
Buy amoxicillin without prescription. Buy amoxicillin online cheap amoxicillin. (more…)
トラックバック by Buy amoxicillin without prescription. — 2008/12/8 月曜日 @ 6:33:26