Spec-Zone.ru › Perl 5.34

perlunitut

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • ОПИСАНИЕ
    • Определения
      • Unicode
      • UTF-8
      • Строки текста (строки символов)
      • Бинарные строки (строки байтов)
      • Кодирование
      • Декодирование
      • Внутренний формат
    • Ваш новый инструментарий
    • Поток ввода/вывода (собственно 5-минутный учебник)
  • РЕЗЮМЕ
  • Вопросы и ответы (или FAQ)
  • БЛАГОДАРНОСТИ
  • АВТОР
  • СМОТРИТЕ ТАКЖЕ

НАЗВАНИЕ

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.34.0/perlunitut

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API