2010-08-13 2 views
3

У меня есть файл данных (например, планшета Apple), который имеет Unicodecodepoints как \U00e8 и \U2019. Мне нужно превратить их в действительные шестнадцатеричные HTML entities с использованием PHP.Как преобразовать кодовые страницы Unicode в шестнадцатеричные объекты HTML?

Что я делаю сейчас является длинная строка:

$fileContents = str_replace("\U00e8", "è", $fileContents); 
$fileContents = str_replace("\U2019", "’", $fileContents); 

Который явно ужасно. Я мог бы использовать регулярное выражение для преобразования \U и всех завершающих 0s в &#x, а затем придерживаться конечного ;, но это также кажется тяжелым.

Есть ли простой и простой способ взять строку и заменить все кодовые страницы юникода на объекты HTML?

+0

Регулярные выражения PCRE довольно быстры и безопасны; Я бы использовал их. (Другие официальные решения, вероятно, тоже будут использовать регулярное выражение. Или таблица поиска, которая у вас есть сейчас.) – MvanGeest

+2

Согласно [этой странице] (http://code.google.com/p/networkpx/wiki/PlistSpec), эти escape-последовательности представляют собой кодовые единицы UTF-16, а не кодовые коды Unicode. Это означает, что вам может понадобиться объединить два последовательных блока кода (если они образуют суррогатную пару), чтобы сформировать объект HTML. – Artefacto

ответ

4

Вы можете использовать preg_replace:

preg_replace('/\\\\U0*([0-9a-fA-F]{1,5})/', '&#x\1;', $fileContents); 

Тестирование RE:

PS> 'some \U00e8 string with \U2019 embedded Unicode' -replace '\\U0*([0-9a-f]{1,5})','&#x$1;' 
some è string with ’ embedded Unicode 
+0

Кажется, что явный вариант использования для регулярного выражения. @Tina Marie, посмотрите http://code.google.com/p/cfpropertylist/, если вам нужна обработка plist. –

+0

yep, используя CFPropertyList. прекрасно работает! –

7

Вот правильный ответ, который имеет дело с тем, что те являются кодовые единицы, а не кодовые точки, и позволяет unencoding дополнительные символы.

function unenc_utf16_code_units($string) { 
    /* go for possible surrogate pairs first */ 
    $string = preg_replace_callback(
     '/\\\\U(D[89ab][0-9a-f]{2})\\\\U(D[c-f][0-9a-f]{2})/i', 
     function ($matches) { 
      $hi_surr = hexdec($matches[1]); 
      $lo_surr = hexdec($matches[2]); 
      $scalar = (0x10000 + (($hi_surr & 0x3FF) << 10) | 
       ($lo_surr & 0x3FF)); 
      return "&#x" . dechex($scalar) . ";"; 
     }, $string); 
    /* now the rest */ 
    $string = preg_replace_callback('/\\\\U([0-9a-f]{4})/i', 
     function ($matches) { 
      //just to remove leading zeros 
      return "&#x" . dechex(hexdec($matches[1])) . ";"; 
     }, $string); 
    return $string; 
} 
Смежные вопросы