perlunitut
СОДЕРЖАНИЕ
НАЗВАНИЕ
perlunitut - Руководство по Unicode для Perl
ОПИСАНИЕ
Эпоха простого обращения со строками прошла. Современные программы должны уметь взаимодействовать с интересными акцентированными буквами и символами, такими как евро. Это означает, что программисты должны придерживаться новых привычек. Легко программировать программное обеспечение, совместимое с Unicode, но для правильной работы необходимо соблюдать дисциплину.
Существует много информации о наборах символов и кодировках текста. Вероятно, лучше потратить целый день на изучение всего этого, но основы можно освоить за несколько минут.
Тем не менее, это не самые основы. Предполагается, что вы уже знаете разницу между байтами и символами и осознаёте (и принимаете!), что существует множество различных наборов символов и кодировок, и что ваша программа должна быть явной об их использовании. Рекомендуется к прочтению статья "Абсолюльно минимальное, что каждый разработчик ПО должен знать об Unicode и наборах символов (без оправданий!)" Джоэла Сполски по адресу http://joelonsoftware.com/articles/Unicode.html.
В этом руководстве используются довольно абсолютные выражения и представлен только ограниченный обзор широкого спектра функций работы со строками символов, которые предоставляет Perl. Для большинства проектов этой информации, вероятно, будет достаточно.
Определения
Сначала важно уяснить несколько моментов. Это самая важная часть этого руководства. Эта точка зрения может противоречить другой информации, которую вы могли найти в Интернете, но это в основном потому, что многие источники неверны.
Возможно, вам придется несколько раз перечитать этот раздел...
Unicode
Unicode — это набор символов, в котором есть место для многих символов. Порядковое значение символа называется кодовой точкой. (Но на практике различие между кодовой точкой и символом размыто, поэтому эти термины часто используются взаимозаменяемо.)
Существует много, много кодовых точек, но компьютеры работают с байтами, а байт может содержать только 256 значений. Unicode содержит гораздо больше символов, чем это, поэтому для доступа к ним нужен метод.
Unicode кодируется с помощью нескольких конкурирующих кодировок, из которых UTF-8 используется чаще всего. В кодировке Unicode для хранения одной кодовой точки или просто: символа могут использоваться несколько последовательных байтов.
UTF-8
UTF-8 — это кодировка Unicode. Многие люди думают, что Unicode и UTF-8 — одно и то же, но это не так. Существует больше кодировок Unicode, но большая часть мира стандартизирована на UTF-8.
UTF-8 обрабатывает первые 128 кодовых точек, 0..127, так же, как ASCII. Они занимают только один байт на символ. Все остальные символы кодируются от двух до четырёх байтов с помощью сложного алгоритма. К счастью, Perl обрабатывает это за нас, так что нам не нужно беспокоиться об этом.
Строки текста (строки символов)
Строки текста или строки символов состоят из символов. Байты здесь не имеют значения, как и кодировки. Каждый символ — это просто символ.
В строке текста вы будете выполнять такие действия, как:
$text =~ s/foo/bar/;
if ($string =~ /^\d+$/) { ... }
$text = ucfirst $text;
my $character_count = length $text; Значение символа (ord, chr) — это соответствующая кодовая точка Unicode.
Бинарные строки (байтовые строки)
Бинарные строки или байтовые строки состоят из байтов. Здесь нет символов, только байты. Все взаимодействие с внешним миром (все, что находится за пределами текущего процесса Perl) выполняется в двоичном формате.
В байтовой строке вы будете выполнять такие действия, как:
my (@length_content) = unpack "(V/a)*", $binary;
$binary =~ s/\x00\x0F/\xFF\xF0/; # for the brave :)
print {$fh} $binary;
my $byte_count = length $binary; Кодирование
Кодирование (как глагол) — это преобразование из текста в двоичный формат. Для кодирования необходимо указать целевую кодировку, например iso-8859-1 или UTF-8. Некоторые кодировки, например диапазон iso-8859 ("латинский"), не поддерживают весь стандарт Unicode; символы, которые нельзя представить, теряются при преобразовании.
Декодирование
Декодирование — это преобразование из двоичного формата в текст. Для декодирования необходимо знать, какая кодировка использовалась во время кодирования. И, самое главное, она должна быть декодируемой. Не имеет смысла декодировать изображение PNG в строку текста.
Внутренний формат
Perl имеет внутренний формат, кодировку, которую он использует для кодирования строк текста, чтобы хранить их в памяти. Все строки текста хранятся в этом внутреннем формате. На самом деле, строки текста никогда не хранятся в каком-либо другом формате!
Вам не нужно беспокоиться о том, что это за формат, потому что преобразование автоматически выполняется при декодировании или кодировании.
Ваш новый набор инструментов
Добавьте в свой стандартный заголовок следующую строку:
use Encode qw(encode decode); Или, если вы ленивы, просто:
use Encode; Поток ввода/вывода (фактическое руководство за 5 минут)
Типичный поток ввода/вывода программы выглядит следующим образом:
1. Receive and decode
2. Process
3. Encode and output Если ваш входной данные — это бинарные данные и они должны оставаться бинарными, вы не должны декодировать их в строку текста, конечно. Но во всех остальных случаях вы должны декодировать их.
Декодирование нельзя выполнить надёжно, если вы не знаете, как были закодированы данные. Если вы можете выбрать, имеет смысл стандартизировать на UTF-8.
my $foo = decode('UTF-8', get 'http://example.com/');
my $bar = decode('ISO-8859-1', readline STDIN);
my $xyzzy = decode('Windows-1251', $cgi->param('foo')); Обработка происходит так же, как вы знали раньше. Единственное отличие в том, что теперь вы используете символы вместо байтов. Это очень полезно, если вы используете такие вещи, как substr, или length.
Важно понимать, что в строке текста нет байтов. Конечно, Perl имеет свою внутреннюю кодировку для хранения строки в памяти, но игнорируйте это. Если вам нужно выполнить какие-либо действия с количеством байтов, лучше всего выполнить эту часть на шаге 3, сразу после кодирования строки. Тогда вы точно знаете, сколько байтов будет в целевой строке.
Синтаксис кодирования строк текста в бинарные строки такой же простой, как и декодирование:
$body = encode('UTF-8', $body); Если вам нужно было узнать длину строки в байтах, сейчас самое подходящее время для этого. Потому что $body теперь является байтовой строкой, length будет сообщать количество байтов, а не количество символов. Количество символов больше не известно, потому что символы существуют только в строках текста.
my $byte_count = length $body; И если используемый вами протокол поддерживает способ уведомления получателя о том, какую кодировку символов вы использовали, пожалуйста, помогите получателю, используя эту функцию! Например, электронная почта и HTTP поддерживают заголовки MIME, поэтому вы можете использовать заголовок Content-Type. Они также могут иметь Content-Length, чтобы указать количество байтов, что всегда хорошая идея, если это число известно.
"Content-Type: text/plain; charset=UTF-8",
"Content-Length: $byte_count" РЕЗЮМЕ
Декодируйте всё, что получаете, кодируйте всё, что отправляете. (Если это текстовые данные.)
Вопросы и ответы (или FAQ)
После прочтения этого документа вам следует также прочитать perlunifaq, а затем perluniintro.
БЛАГОДАРНОСТИ
Благодарим Йохана Вроманса из Squirrel Consultancy. Его размышления об UTF-8 во время встреч Perl Mongers в Амстердаме заинтересовали меня и побудили меня выяснить, как использовать кодировки символов в Perl таким образом, чтобы они не ломались.
Благодарим Герарда Гуссена из TTY. Его презентация «UTF-8 в дикой природе» (Голландский Perl Workshop 2006) вдохновила меня опубликовать мои мысли и написать это руководство.
Благодарим людей, которые спрашивали об этом в различных каналах Perl IRC и постоянно напоминали мне о необходимости более простого объяснения.
Благодарим людей, которые просмотрели этот документ, прежде чем он был опубликован. Это: Benjamin Smith, Jan-Pieter Cornet, Johan Vromans, Lukas Mai, Nathan Gray.
АВТОР
Juerd Waalboer <#####@juerd.nl>
СМОТРИТЕ ТАКЖЕ
perlunifaq, perlunicode, perluniintro, Encode
© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.36.0/perlunitut