note 93162 added to function.utf8-encode

From: Date: Wed, 26 Aug 2009 13:20:46 +0000
Subject: note 93162 added to function.utf8-encode
Groups: php.notes 
Request: Send a blank email to php-notes+get-159901@lists.php.net to get a copy of this message
I think this is a reasonable port of Perl's Encoding::FixLatin by Grant McLean, which converts a string with mixed encodings (ASCII, ISO-8859-1, CP1252, and UTF-8) to UTF-8. <?php function init_byte_map(){ global $byte_map; for($x=128;$x<256;++$x){ $byte_map[chr($x)]=utf8_encode(chr($x)); } $cp1252_map=array( "\x80"=>"\xE2\x82\xAC", // EURO SIGN "\x82" => "\xE2\x80\x9A", // SINGLE LOW-9 QUOTATION MARK "\x83" => "\xC6\x92", // LATIN SMALL LETTER F WITH HOOK "\x84" => "\xE2\x80\x9E", // DOUBLE LOW-9 QUOTATION MARK "\x85" => "\xE2\x80\xA6", // HORIZONTAL ELLIPSIS "\x86" => "\xE2\x80\xA0", // DAGGER "\x87" => "\xE2\x80\xA1", // DOUBLE DAGGER "\x88" => "\xCB\x86", // MODIFIER LETTER CIRCUMFLEX ACCENT "\x89" => "\xE2\x80\xB0", // PER MILLE SIGN "\x8A" => "\xC5\xA0", // LATIN CAPITAL LETTER S WITH CARON "\x8B" => "\xE2\x80\xB9", // SINGLE LEFT-POINTING ANGLE QUOTATION MARK "\x8C" => "\xC5\x92", // LATIN CAPITAL LIGATURE OE "\x8E" => "\xC5\xBD", // LATIN CAPITAL LETTER Z WITH CARON "\x91" => "\xE2\x80\x98", // LEFT SINGLE QUOTATION MARK "\x92" => "\xE2\x80\x99", // RIGHT SINGLE QUOTATION MARK "\x93" => "\xE2\x80\x9C", // LEFT DOUBLE QUOTATION MARK "\x94" => "\xE2\x80\x9D", // RIGHT DOUBLE QUOTATION MARK "\x95" => "\xE2\x80\xA2", // BULLET "\x96" => "\xE2\x80\x93", // EN DASH "\x97" => "\xE2\x80\x94", // EM DASH "\x98" => "\xCB\x9C", // SMALL TILDE "\x99" => "\xE2\x84\xA2", // TRADE MARK SIGN "\x9A" => "\xC5\xA1", // LATIN SMALL LETTER S WITH CARON "\x9B" => "\xE2\x80\xBA", // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK "\x9C" => "\xC5\x93", // LATIN SMALL LIGATURE OE "\x9E" => "\xC5\xBE", // LATIN SMALL LETTER Z WITH CARON "\x9F" => "\xC5\xB8" // LATIN CAPITAL LETTER Y WITH DIAERESIS ); foreach($cp1252_map as $k=>$v){ $byte_map[$k]=$v; } } function fix_latin($instr){ if(mb_check_encoding($instr,'UTF-8'))return $instr; // no need for the rest if it's all valid UTF-8 already global $nibble_good_chars,$byte_map; $outstr=''; $char=''; $rest=''; while((strlen($instr))>0){ if(1==preg_match($nibble_good_chars,$input,$match)){ $char=$match[1]; $rest=$match[2]; $outstr.=$char; }elseif(1==preg_match('@^(.)(.*)$@s',$input,$match)){ $char=$match[1]; $rest=$match[2]; $outstr.=$byte_map[$char]; } $instr=$rest; } return $outstr; } $byte_map=array(); init_byte_map(); $ascii_char='[\x00-\x7F]'; $cont_byte='[\x80-\xBF]'; $utf8_2='[\xC0-\xDF]'.$cont_byte; $utf8_3='[\xE0-\xEF]'.$cont_byte.'{2}'; $utf8_4='[\xF0-\xF7]'.$cont_byte.'{3}'; $utf8_5='[\xF8-\xFB]'.$cont_byte.'{4}'; $nibble_good_chars = "@^($ascii_char+|$utf8_2|$utf8_3|$utf8_4|$utf8_5)(.*)$@s"; ?> Then just call fix_latin wherever you need it. ---- Server IP: 208.69.120.35 Probable Submitter: 72.174.41.7 ---- Manual Page -- http://www.php.net/manual/en/function.utf8-encode.php Edit -- https://master.php.net/note/edit/93162 Del: integrated -- https://master.php.net/note/delete/93162/integrated Del: useless -- https://master.php.net/note/delete/93162/useless Del: bad code -- https://master.php.net/note/delete/93162/bad+code Del: spam -- https://master.php.net/note/delete/93162/spam Del: non-english -- https://master.php.net/note/delete/93162/non-english Del: in docs -- https://master.php.net/note/delete/93162/in+docs Del: other reasons-- https://master.php.net/note/delete/93162 Reject -- https://master.php.net/note/reject/93162 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#159901) next »