 |
ПЕРЕКОДИРУЕМ ASCII+ENTITIES В UNICODE: ДЕЛАЕМ НА PHP И НЕ ПАРИМСЯ, БОНУС - UTF8
Задача
Конвертировать ascii-файл с латинскими и русскими буквами и html-последовательностями (entities) в unicode и utf-8.
Почему
Ну, это сейчас модно :) а на практике - чтобы скормить текст какому-нибудь приложению, которое entities не понимает. И это так естественно, оно же не броузер...
Откуда
Ноги растут из примерно этого, видимого на странице сайта:
sans gêne безъ стѣсненія (фр.)
Внутри текстового файла эта смесь "французского с нижегородским" выглядит так:
sans gêne — безъ стѣсненія <i> (фр.)</i>
1. Составляем таблицу перекодировки
Данные тырим тут: www.utf8-chartable.de
По ссылке надо использовать таблицы Basic Latin, General Punctuation и Cyrillic.
Нам нужна таблица примерно такого вида для всех русских и латинских символов, включая всякие диакритические знаки:
Юникод|Буква|Entity|Название <- эту строчку надо выкинуть! ................... U+0400||Ѐ|CYRILLIC CAPITAL LETTER IE WITH GRAVE U+0401|Ё|Ё|CYRILLIC CAPITAL LETTER IO U+0402||Ђ|CYRILLIC CAPITAL LETTER DJE ................... U+004C|L|L|LATIN CAPITAL LETTER L U+004D|M|M|LATIN CAPITAL LETTER M ................... U+00CA||Ê|LATIN CAPITAL LETTER E WITH CIRCUMFLEX U+00CA||ê|LATIN CAPITAL LETTER E WITH CIRCUMFLEX ...................
Метод годится только для четырехзначных юникодов U+xxxx.
Там где буква не видна в вашем текстовом редакторе, крюкозябру просто удаляем. НЕ удаляем пробел и неразрывный пробел. Колонка "Название" нужна только для ориентирования. Обратите внимание на две последние строки примера - текстовой entity в первоисточнике нет, добавляем ручками.
2. Делаем из таблицы массив
Для каждой строки (выкинув заголовок:) формируем половинки массива перекодировки: $fpcode = fopen('codetable.txt','r'); $part1 = array(); $part2 = array(); while(!feof($fpcode)) { $stroka = explode('|',trim($stroka)); $hex = chr(hexdec(substr($stroka[0],4,2))).chr(hexdec(substr($stroka[0],2,2))); if ($stroka[2]!='') $part1[$stroka[2]] = $hex; if ($stroka[1]!='') $part2[$stroka[1]] = $hex; }
А затем объединяем эти половинки, обязательно в таком порядке: $trans = array_merge($part1,$part2);
Массив можно было бы задать прямо в коде, но предложенный способ - самый ленивый.
3. Перекодируем!
Открываем входной и выходной файлы: $fpin = fopen('in-ascii.txt','r'); $fpout = fopen('out-unicode.txt','w');
Пишем в выходной файл заголовок ака хедер (BOM - byte order mark): fwrite($fpout,"\xFF\xFE");
A теперь читаем входной файл построчно, перекодируем строку и записываем ее в выходной файл с переводом строки: while(!feof($fpin)) { $buffer = fgets($fpin); fwrite($fpout,strtr(trim($buffer),$trans)."\x0D\x00\x0A\x00"); }
Странную очередность байтов даже не пытаемся понять, пишем именно так и всё.
4. Бонус
Открываем полученный текст Блокнотом, например. Замечаем, что даже Блокнот умудряется понять кодировку unicode.
Если не видны спецсимволы, назначаем нужный шрифт показа, Palatino Linotype, например. На сам текст это никак не влияет.
Сохраняем файл как... под другим именем, выбрав в окошечке кодировку UTF-8.
Вуаля, знамо дѣло!
|
 |