Existe-t-il une fonction en PHP qui peut décoder les séquences d'échappement Unicode comme " \u00ed
" à " í
" et toutes les autres occurrences similaires ?
J'ai trouvé une question similaire aquí mais cela ne semble pas fonctionner.
Existe-t-il une fonction en PHP qui peut décoder les séquences d'échappement Unicode comme " \u00ed
" à " í
" et toutes les autres occurrences similaires ?
J'ai trouvé une question similaire aquí mais cela ne semble pas fonctionner.
Essayez ça :
$str = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}, $str);
Dans le cas où il s'agit d'un style C/C++/Java/Json basé sur UTF-16 :
$str = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE');
}, $str);
@Docstero : L'expression régulière correspondra à toute séquence de \u
suivi de quatre chiffres hexadécimaux.
Attention : preg_replace_callback() [function.preg-replace-callback] : La compilation a échoué : PCRE ne supporte pas \L , \l , \N , \U ou \u à l'offset 1
Cette fonction ne peut pas traiter les caractères supplémentaires car ils ne peuvent pas être représentés en UCS-2.
Il est intéressant de noter que cela fonctionne également pour des entités complexes comme les smileys... json_decode('{"t":"\uD83D\uDE0A"}')
es
Depuis PHP 7, vous pouvez utiliser l'option Syntaxe d'échappement des points de code Unicode pour le faire.
echo "\u{00ed}";
sorties í
.
$str = '\u0063\u0061\u0074'.'\ud83d\ude38';
$str2 = '\u0063\u0061\u0074'.'\ud83d';
// U+1F638
var_dump(
"cat\xF0\x9F\x98\xB8" === escape_sequence_decode($str),
"cat\xEF\xBF\xBD" === escape_sequence_decode($str2)
);
function escape_sequence_decode($str) {
// [U+D800 - U+DBFF][U+DC00 - U+DFFF]|[U+0000 - U+FFFF]
$regex = '/\\\u([dD][89abAB][\da-fA-F]{2})\\\u([dD][c-fC-F][\da-fA-F]{2})
|\\\u([\da-fA-F]{4})/sx';
return preg_replace_callback($regex, function($matches) {
if (isset($matches[3])) {
$cp = hexdec($matches[3]);
} else {
$lead = hexdec($matches[1]);
$trail = hexdec($matches[2]);
// http://unicode.org/faq/utf_bom.html#utf16-4
$cp = ($lead << 10) + $trail + 0x10000 - (0xD800 << 10) - 0xDC00;
}
// https://tools.ietf.org/html/rfc3629#section-3
// Characters between U+D800 and U+DFFF are not allowed in UTF-8
if ($cp > 0xD7FF && 0xE000 > $cp) {
$cp = 0xFFFD;
}
// https://github.com/php/php-src/blob/php-5.6.4/ext/standard/html.c#L471
// php_utf32_utf8(unsigned char *buf, unsigned k)
if ($cp < 0x80) {
return chr($cp);
} else if ($cp < 0xA0) {
return chr(0xC0 | $cp >> 6).chr(0x80 | $cp & 0x3F);
}
return html_entity_decode('&#'.$cp.';');
}, $str);
}
Il s'agit d'une approche brutale pour remplacer l'UNICODE brut par du HTML. Je n'ai pas vu d'autre endroit pour mettre cette solution, mais je suppose que d'autres ont eu ce problème.
Appliquer cette fonction str_replace à la RAW JSON avant de faire quoi que ce soit autre chose.
function unicode2html($str){
$i=65535;
while($i>0){
$hex=dechex($i);
$str=str_replace("\u$hex","&#$i;",$str);
$i--;
}
return $str;
}
Cela ne prendra pas autant de temps que vous le pensez, et cela remplacera n'importe quel unicode par du HTML.
Bien sûr, cela peut être réduit si vous connaissez les types unicode qui sont retournés dans le JSON.
Par exemple, mon code recevait beaucoup de flèches et d'unicode dingbat. Ceux-ci sont compris entre 8448 et 11263. Donc mon code de production ressemble à :
$i=11263;
while($i>08448){
...etc...
Vous pouvez consulter les blocs d'Unicode par type ici : http://unicode-table.com/en/ Si vous savez que vous traduisez de l'arabe ou du telegu ou autre, vous pouvez juste remplacer ces codes, pas les 65 000.
Vous pourriez appliquer cette même méthode à l'encodage simple :
$str=str_replace("\u$hex",chr($i),$str);
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.