Чтение и запись файлов XML с неизвестной кодировкой в ​​Perl? - PullRequest
1 голос
/ 28 мая 2011

Я собираю куски чужого крупного проекта и пытаюсь исправить ошибки. Проблема в том, что я просто не уверен, какие правильные способы .

Итак, я собираю кучу HTML-страниц, а затем записываю их в файлы с помощью простых команд, таких как:

$src = `curl http://google.com`;
open FILE, ">output.html";
print FILE $src;
close FILE;

Теперь я хотел, чтобы они были сохранены как UTF-8. Как это сохраняется? Затем я читаю html-файл, используя ту же базовую команду «open», анализирую html с помощью вызовов regex и использую конкатенацию строк, чтобы создать большую строку, и записываю ее в XML-файл (используя тот же код, что и выше). Вместо этого я уже начал использовать XML :: Writer, но теперь мне нужно пройтись и исправить файлы с неточной кодировкой.

Итак, у меня больше нет html, но у меня все еще есть XML, который должен отображать правильные символы. Вот пример: http://filevo.com/wkkixmebxlmh.html

Основная проблема заключается в обнаружении и замене соответствующего символа на "\ x {2019}", который правильно отображается в редакторах. Но я не могу найти регулярное выражение, чтобы на самом деле захватить персонажа в дикой природе.

UPDATE:

Я все еще не могу обнаружить символ ALT-0146, который находится в файле XML, который я загрузил в Filevo выше. Я попытался открыть его в UTF-8 и найти / \ x {2019} /, / chr (0x2019) /, и просто / ’/, ничего.

Ответы [ 3 ]

4 голосов
/ 28 мая 2011

Обнаружение кодировки HTML-документа hard . См. http://blog.whatwg.org/the-road-to-html-5-character-encoding и, в особенности, что он требует «7-шагового алгоритма; шаг 4 имеет 2 подэтапа, первый из которых имеет 7 ветвей, один из которых имеет 8 подэтапов, один из которых фактически связан с отдельный алгоритм, который сам по себе имеет 7 шагов ... Это продолжается некоторое время. "

Это то, что я использовал для моих ограниченных потребностей в разборе файлов HTML.

my $CHARACTER_SET_CLASS = '\w:.()-';

     # X(HT)?ML: http://www.w3.org/International/O-charset
     /\<\?xml [^>]*(?<= )encoding=[\'\"]?([$CHARACTER_SET_CLASS]+)/ ||
     # X?HTML: http://blog.whatwg.org/the-road-to-html-5-character-encoding
     /\<meta [^>]*\bcharset=["']?([$CHARACTER_SET_CLASS]+)/i ||
     # CSS: http://www.w3.org/International/questions/qa-css-charset
     /\@charset "([^\"]*)"/ ||
3 голосов
/ 28 мая 2011

Чтобы убедиться, что вы производите вывод в UTF-8, примените слой utf8 к выходному потоку, используя binmode

open FILE, '>output.html';
binmode FILE, ':utf8';

или в 3-аргументе open вызов

open FILE, '>:utf8', 'output.html'

Произвольный ввод сложнее.Если вам повезет, то в начале HTML-код сообщит вам свою кодировку:

wget http://www.google.com/ -O foo ; head -1 foo

<!doctype html><html><head><meta http-equiv="content-type" content="text/html; 
charset=ISO-8859-1"><title>Google</title><script>window.google=
{kEI:"xgngTYnYIoPbgQevid3cCg",kEXPI:"23933,28505,29134,29229,29658,
29695,29795,29822,29892,30111,30174,30215,30275,30562",kCSI:
{e:"23933,28505,29134,29229,29658,29695,29795,29822,29892,30111,
30174,30215,30275,30562",ei:"xgngTYnYIoPbgQevid3cCg",expi:
"23933,28505,29134,29229,29658,29695,29795,29822,29892,30111,
30174,30215,30275,30562"},authuser:0,ml:function(){},kHL:"en",
time:function(){return(new Date).getTime()},

Ах, вот оно: <meta http-equiv="content-type" <B>content="text/html; charset=ISO-8859-1</B>">.Теперь вы можете продолжить читать входные данные как необработанные байты и найти способ декодировать эти байты с помощью известной кодировки. CPAN может помочь с этим.

1 голос
/ 28 мая 2011

Я имею в виду обновленную часть вашего вопроса (в следующий раз откройте новую для отдельной темы).Это шестнадцатеричный дамп вашего файла (в будущем, пожалуйста, воздержитесь от того, чтобы помощники перепрыгивали через горящие обручи, чтобы получить данные вашего примера):

0000  3c 78 6d 6c 3e 0d 0a 3c  70 65 72 73 6f 6e 4e 61  <xml>␍␤< personNa
0010  6d 65 3e 47 2e 20 50 65  74 65 72 20 44 61 80 41  me>G. Pe ter Da�A
0020  6c 6f 69 61 3c 2f 70 65  72 73 6f 6e 4e 61 6d 65  loia</pe rsonName
0030  3e 0d 0a 3c 2f 78 6d 6c  3e 0d 0a                 >␍␤</xml >␍␤

Вы сказали, что знаете, что символ должен быть ,но это стало полностью изуродованным.Это не может быть 0x80 в любой кодировке.Это похоже на случай вставки, когда вы переносили данные между редакторами / буфером обмена, а не работали только с файлами.Если это не так, значит, ваш коровий ордер допустил ошибку, которую вы не можете исправить алгоритмически.

...