Spec-Zone.ru › Perl 5.38

Encode

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНОПСИС
    • Оглавление
  • ОПИСАНИЕ
    • ТЕРМИНОЛОГИЯ
      • символ
      • байт
      • октет
  • API КОДИРОВАНИЯ PERL
    • Основные методы
      • encode
      • decode
      • find_encoding
      • find_mime_encoding
      • from_to
      • encode_utf8
      • decode_utf8
    • Список доступных кодировок
    • Определение псевдонимов
    • Поиск имён в реестре кодировок IANA
  • Кодирование через PerlIO
  • Обработка повреждённых данных
    • Список значений CHECK
      • FB_DEFAULT
      • FB_CROAK
      • FB_QUIET
      • FB_WARN
      • FB_PERLQQ FB_HTMLCREF FB_XMLCREF
      • Битовая маска
      • LEAVE_SRC
    • coderef для CHECK
  • Определение кодировок
  • Флаг UTF8
    • Взаимодействие с внутренними компонентами Perl
      • is_utf8
      • _utf8_on
      • _utf8_off
  • UTF-8 против utf8 против UTF8
  • СМОТРИТЕ ТАКЖЕ
  • ОБНОВИТЕЛЬ
  • АВТОРСКИЕ ПРАВА

ИМЯ

Encode - кодировки символов в Perl

СИНОПСИС

use Encode qw(decode encode);
$characters = decode('UTF-8', $octets,     Encode::FB_CROAK);
$octets     = encode('UTF-8', $characters, Encode::FB_CROAK);

Оглавление

Encode состоит из набора модулей, подробности которых слишком обширны, чтобы уместиться в одном документе. Этот документ объясняет API верхнего уровня и общие темы в общих чертах. Для других тем и более подробных сведений см. документацию по этим модулям:

Encode::Alias - Определения псевдонимов для кодировок
Encode::Encoding - Базовый класс реализации кодирования
Encode::Supported - Список поддерживаемых кодировок
Encode::CN - Кодировки упрощённого китайского
Encode::JP - Кодировки японского языка
Encode::KR - Кодировки корейского языка
Encode::TW - Кодировки традиционного китайского

ОПИСАНИЕ

Модуль Encode предоставляет интерфейс между строками Perl и остальной частью системы. Строки Perl являются последовательностями символов.

Набор символов, который Perl может представлять, является супермножеством символов, определенных Консорциумом Unicode. На большинстве платформ порядковые значения символа, возвращаемые ord(S), являются кодовой точкой Unicode для этого символа. Исключение составляют платформы, где стандартная кодировка является разновидностью EBCDIC, а не супермножеством ASCII; см. perlebcdic.

В последнее время данные перемещаются по компьютеру в 8-битных блоках, часто называемых «байтами», но также известными как «октеты» в документации стандартов. Perl широко используется для обработки данных различных типов: не только строк символов, представляющих человеческие или компьютерные языки, но также «бинарных» данных, представляющих представление чисел машиной, пикселей на изображении или практически чего угодно.

Когда Perl обрабатывает «бинарные данные», программист хочет, чтобы Perl обрабатывал «последовательности байтов». Это не проблема для Perl: поскольку байт имеет 256 возможных значений, он легко помещается в гораздо более широкий «логический символ» Perl.

Этот документ в основном объясняет как. perlunitut и perlunifaq объясняют почему.

ТЕРМИНОЛОГИЯ

символ

Символ в диапазоне 0 .. 2**32-1 (или больше); из чего состоят строки Perl.

байт

Символ в диапазоне 0..255; частный случай символа Perl.

октет

8 бит данных с порядковыми значениями 0..255; термин для байтов, передаваемых в или из контекста, отличного от Perl, такого как файл на диске, поток стандартного ввода/вывода, база данных, аргумент командной строки, переменная среды, сокет и т. д.

API КОДИРОВАНИЯ PERL

Основные методы

encode

$octets  = encode(ENCODING, STRING[, CHECK])

Кодирует скалярное значение STRING из внутреннего формата Perl в ENCODING и возвращает последовательность октетов. ENCODING может быть либо каноническим именем, либо псевдонимом. Для имен кодировок и псевдонимов см. "Определение псевдонимов". Для CHECK см. "Обработка повреждённых данных".

ПРЕДУПРЕЖДЕНИЕ: входной скаляр STRING может быть изменён на месте в зависимости от установленного значения CHECK. См. "LEAVE_SRC", если вы хотите, чтобы ваши входные данные оставались неизменными.

Например, для преобразования строки из внутреннего формата Perl в ISO-8859-1, также известной как Latin1:

$octets = encode("iso-8859-1", $string);

ПРЕДУПРЕЖДЕНИЕ: При выполнении $octets = encode("UTF-8", $string), $octets может не быть равен $string. Хотя оба содержат одни и те же данные, флаг UTF8 для $octets всегда выключен. При кодировании чего-либо флаг UTF8 на результате всегда выключен, даже если он содержит полностью корректную строку UTF-8. См. "Флаг UTF8" ниже.

Если $string равен undef, то возвращается undef.

str2bytes может использоваться как псевдоним для encode.

decode

$string = decode(ENCODING, OCTETS[, CHECK])

Эта функция возвращает строку, которая получается в результате декодирования скалярного значения OCTETS, предполагаемого как последовательность октетов в ENCODING, во внутренний формат Perl. Как и в случае с encode(), ENCODING может быть либо каноническим именем, либо псевдонимом. Для имен кодировок и псевдонимов см. "Определение псевдонимов", для CHECK см. "Обработка повреждённых данных".

ПРЕДУПРЕЖДЕНИЕ: входной скаляр OCTETS может быть изменён на месте в зависимости от установленного значения CHECK. См. "LEAVE_SRC", если вы хотите, чтобы ваши входные данные оставались неизменными.

Например, для преобразования данных ISO-8859-1 в строку во внутреннем формате Perl:

$string = decode("iso-8859-1", $octets);

ПРЕДУПРЕЖДЕНИЕ: При выполнении $string = decode("UTF-8", $octets), $string может не быть равен $octets. Хотя оба содержат одни и те же данные, флаг UTF8 для $string включён. См. "Флаг UTF8" ниже.

Если $string равен undef, то возвращается undef.

bytes2str может использоваться как псевдоним для decode.

find_encoding

[$obj =] find_encoding(ENCODING)

Возвращает объект кодирования, соответствующий ENCODING. Возвращает undef, если соответствующее ENCODING не найдено. Возвращённый объект выполняет фактическое кодирование или декодирование.

$string = decode($name, $bytes);

фактически

$string = do {
    $obj = find_encoding($name);
    croak qq(encoding "$name" not found) unless ref $obj;
    $obj->decode($bytes);
};

с дополнительной проверкой ошибок.

Таким образом, вы можете сэкономить время, повторно используя этот объект следующим образом;

my $enc = find_encoding("iso-8859-1");
while(<>) {
    my $string = $enc->decode($_);
    ... # now do something with $string;
}

Помимо "decode" и "encode", доступны и другие методы. Например, name() возвращает каноническое имя объекта кодирования.

find_encoding("latin1")->name; # iso-8859-1

См. Encode::Encoding для получения дополнительных сведений.

find_mime_encoding

[$obj =] find_mime_encoding(MIME_ENCODING)

Возвращает объект кодирования, соответствующий MIME_ENCODING. Действует так же, как find_encoding(), но mime_name() возвращаемого объекта должно совпадать с MIME_ENCODING. Итак, в отличие от find_encoding(), при поиске объекта не используются канонические имена и псевдонимы.

find_mime_encoding("utf8"); # returns undef because "utf8" is not valid I<MIME_ENCODING>
find_mime_encoding("utf-8"); # returns encode object "utf-8-strict"
find_mime_encoding("UTF-8"); # same as "utf-8" because I<MIME_ENCODING> is case insensitive
find_mime_encoding("utf-8-strict"); returns undef because "utf-8-strict" is not valid I<MIME_ENCODING>

from_to

[$length =] from_to($octets, FROM_ENC, TO_ENC [, CHECK])

Преобразует данные на месте между двумя кодировками. Данные в $octets должны быть закодированы как октеты, а не как символы во внутреннем формате Perl. Например, для преобразования данных ISO-8859-1 в кодировку CP1250 Microsoft:

from_to($octets, "iso-8859-1", "cp1250");

и для преобразования обратно:

from_to($octets, "cp1250", "iso-8859-1");

Поскольку преобразование происходит на месте, преобразуемые данные не могут быть константой строки: они должны быть скалярной переменной.

from_to() возвращает длину преобразованной строки в октетах при успехе и undef при ошибке.

ПРЕДУПРЕЖДЕНИЕ: следующие операции могут выглядеть одинаково, но таковыми не являются:

from_to($data, "iso-8859-1", "UTF-8"); #1
$data = decode("iso-8859-1", $data);  #2

В обоих случаях #1 и #2 $data состоит из полностью корректной строки UTF-8, но только #2 включает флаг UTF8. #1 эквивалентно:

$data = encode("UTF-8", decode("iso-8859-1", $data));

См. "Флаг UTF8" ниже.

Также обратите внимание на то, что:

from_to($octets, $from, $to, $check);

эквивалентно:

$octets = encode($to, decode($from, $octets), $check);

Да, он не учитывает $check при декодировании. Это сделано намеренно. Если вам нужен точный контроль, используйте decode в сочетании с encode, как показано ниже:

$octets = encode($to, decode($from, $octets, $check_from), $check_to);

encode_utf8

$octets = encode_utf8($string);

ПРЕДУПРЕЖДЕНИЕ: Эта функция может генерировать некорректную UTF-8! Не используйте её для обмена данными. Если вам не нужен более старый "свободный" режим Perl, предпочтительнее $octets = encode("UTF-8", $string).

Эквивалентно $octets = encode("utf8", $string). Символы в $string закодированы во внутреннем формате Perl, и результат возвращается как последовательность октетов. Поскольку все возможные символы в Perl имеют (в широком, а не строгом смысле) представление utf8, эта функция не может потерпеть неудачу.

decode_utf8

$string = decode_utf8($octets [, CHECK]);

ПРЕДУПРЕЖДЕНИЕ: Эта функция принимает недопустимый UTF-8! Не используйте её для обмена данными. Если вы не хотите использовать более старый «мягкий» режим Perl, предпочтительнее $string = decode("UTF-8", $octets [, CHECK]).

Эквивалентно $string = decode("utf8", $octets [, CHECK]). Последовательность октетов, представленная $octets, декодируется из (в широком, а не строгом смысле) utf8 в последовательность логических символов. Поскольку не все последовательности октетов являются допустимым нестрогим utf8, эта функция может потерпеть неудачу. Для проверки см. "Обработка некорректных данных".

ПРЕДУПРЕЖДЕНИЕ: входной параметр $octets может быть изменён на месте в зависимости от значения CHECK. См. "LEAVE_SRC", если вы хотите, чтобы ваши входные данные оставались неизменными.

Перечисление доступных кодировок

use Encode;
@list = Encode->encodings();

Возвращает список канонических имён доступных кодировок, которые уже загружены. Чтобы получить список всех доступных кодировок, включая те, которые ещё не загружены, используйте:

@all_encodings = Encode->encodings(":all");

Или вы можете указать имя конкретного модуля:

@with_jp = Encode->encodings("Encode::JP");

Когда "::" отсутствует в имени, предполагается "Encode::".

@ebcdic = Encode->encodings("EBCDIC");

Чтобы подробно узнать, какие кодировки поддерживает этот пакет, см. Encode::Supported.

Определение псевдонимов

Чтобы добавить новый псевдоним к заданной кодировке, используйте:

use Encode;
use Encode::Alias;
define_alias(NEWNAME => ENCODING);

После этого NEWNAME можно использовать в качестве псевдонима для ENCODING. ENCODING может быть либо именем кодировки, либо объектом кодировки.

Перед этим убедитесь, что псевдоним не существует, используя resolve_alias(), которая возвращает каноническое имя. Например:

Encode::resolve_alias("latin1") eq "iso-8859-1" # true
Encode::resolve_alias("iso-8859-12")   # false; nonexistent
Encode::resolve_alias($name) eq $name  # true if $name is canonical

resolve_alias() не нуждается в use Encode::Alias; его можно импортировать через use Encode qw(resolve_alias).

Подробности см. в Encode::Alias.

Поиск имён из реестра кодировок IANA

Каноническое имя заданной кодировки необязательно совпадает с реестром кодировок IANA, обычно обозначаемым как Content-Type: text/plain; charset=WHATEVER. В большинстве случаев каноническое имя работает, но иногда это не так, особенно с «utf-8-strict».

Начиная с версии Encode 2.21, был добавлен новый метод mime_name().

use Encode;
my $enc = find_encoding("UTF-8");
warn $enc->name;      # utf-8-strict
warn $enc->mime_name; # UTF-8

См. также: Encode::Encoding

Кодирование через PerlIO

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

### Version 1 via PerlIO
  open(INPUT,  "< :encoding(shiftjis)", $infile)
      || die "Can't open < $infile for reading: $!";
  open(OUTPUT, "> :encoding(euc-jp)",  $outfile)
      || die "Can't open > $output for writing: $!";
  while (<INPUT>) {   # auto decodes $_
      print OUTPUT;   # auto encodes $_
  }
  close(INPUT)   || die "can't close $infile: $!";
  close(OUTPUT)  || die "can't close $outfile: $!";

### Version 2 via from_to()
  open(INPUT,  "< :raw", $infile)
      || die "Can't open < $infile for reading: $!";
  open(OUTPUT, "> :raw",  $outfile)
      || die "Can't open > $output for writing: $!";

  while (<INPUT>) {
      from_to($_, "shiftjis", "euc-jp", 1);  # switch encoding
      print OUTPUT;   # emit raw (but properly encoded) data
  }
  close(INPUT)   || die "can't close $infile: $!";
  close(OUTPUT)  || die "can't close $outfile: $!";

В первом варианте вы позволяете соответствующему слою кодировки обрабатывать преобразование. Во втором вы явно преобразуете из одной кодировки в другую.

К сожалению, может случиться так, что кодировки не являются PerlIO-совместимыми. Вы можете проверить, поддерживается ли ваша кодировка в PerlIO, вызвав метод perlio_ok на ней:

Encode::perlio_ok("hz");             # false
find_encoding("euc-cn")->perlio_ok;  # true wherever PerlIO is available

use Encode qw(perlio_ok);            # imported upon request
perlio_ok("euc-jp")

К счастью, все кодировки, входящие в состав ядра Encode, являются PerlIO-совместимыми, за исключением hz и ISO-2022-kr. Подробности см. в Encode::Encoding и Encode::PerlIO.

Обработка некорректных данных

Необязательный аргумент CHECK указывает Encode что делать при обнаружении некорректных данных. Без CHECK предполагается Encode::FB_DEFAULT (== 0).

Начиная с версии 2.12, Encode поддерживает значения coderef для CHECK; см. ниже.

ПРИМЕЧАНИЕ: Не все кодировки поддерживают эту функцию. Некоторые кодировки игнорируют аргумент CHECK. Например, Encode::Unicode игнорирует CHECK и всегда генерирует ошибку.

Список значений CHECK

FB_DEFAULT

I<CHECK> = Encode::FB_DEFAULT ( == 0)

Если CHECK равно 0, кодирование и декодирование заменяют любой некорректный символ на замещающий символ. При кодировании используется SUBCHAR. При декодировании используется универсальный символ замены, код U+FFFD. Если данные предполагаются UTF-8, выдаётся необязательное лексическое предупреждение категории "utf8".

FB_CROAK

I<CHECK> = Encode::FB_CROAK ( == 1)

Если CHECK равно 1, методы немедленно завершаются с сообщением об ошибке. Поэтому при CHECK, равном 1, следует обрабатывать исключения с помощью eval{}, если вы не хотите позволить ему die.

FB_QUIET

I<CHECK> = Encode::FB_QUIET

Если CHECK установлено в Encode::FB_QUIET, кодирование и декодирование немедленно возвращают часть данных, которая была обработана до возникновения ошибки. Аргумент данных перезаписывается всем, что после этого; то есть, необработанной частью данных. Это удобно, когда вам нужно вызывать decode многократно в случае, если ваши исходные данные могут содержать частичные многобайтовые последовательности символов (то есть, вы читаете с буфером фиксированной ширины). Вот пример кода, который делает именно это:

my($buffer, $string) = ("", "");
while (read($fh, $buffer, 256, length($buffer))) {
    $string .= decode($encoding, $buffer, Encode::FB_QUIET);
    # $buffer now contains the unprocessed partial character
}

FB_WARN

I<CHECK> = Encode::FB_WARN

Это то же самое, что и FB_QUIET выше, за исключением того, что вместо молчания при ошибках он выдаёт предупреждение. Это удобно, когда вы отлаживаете код.

ПРЕДУПРЕЖДЕНИЕ: Все предупреждения от модуля Encode сообщаются независимо от настроек pragma warnings. Если вы хотите следовать настройкам лексических предупреждений, заданным pragma warnings, добавьте также значение проверки ENCODE::ONLY_PRAGMA_WARNINGS. Это значение доступно начиная с версии Encode 2.99.

FB_PERLQQ FB_HTMLCREF FB_XMLCREF

режим perlqq (CHECK = Encode::FB_PERLQQ)
режим charref HTML (CHECK = Encode::FB_HTMLCREF)
режим charref XML (CHECK = Encode::FB_XMLCREF)

Для кодировок, реализованных модулем Encode::XS, CHECK == Encode::FB_PERLQQ помещает encode и decode в режим падения по умолчанию perlqq.

При декодировании вставлен \xHH, где HH — шестнадцатеричное представление октета, который не удалось декодировать до utf8. При кодировании будет вставлен \x{HHHH}, где HHHH — код Юникода (в любом количестве шестнадцатеричных цифр) символа, который не найден в наборе символов кодировки.

Режимы ссылок на символы HTML/XML одинаковы. Вместо \x{HHHH}, HTML использует &#NNN;, где NNN — десятичное число, а XML использует &#xHHHH;, где HHHH — шестнадцатеричное число.

В Encode версии 2.10 или позднее, LEAVE_SRC также подразумевается.

Побитовая маска

Все эти режимы фактически задаются с помощью побитовой маски. Вот как расположены константы FB_XXX. Вы можете импортировать константы FB_XXX через use Encode qw(:fallbacks), а общие константы побитовой маски через use Encode qw(:fallback_all).

                    FB_DEFAULT FB_CROAK FB_QUIET FB_WARN  FB_PERLQQ
DIE_ON_ERR    0x0001             X
WARN_ON_ERR   0x0002                               X
RETURN_ON_ERR 0x0004                      X        X
LEAVE_SRC     0x0008                                        X
PERLQQ        0x0100                                        X
HTMLCREF      0x0200
XMLCREF       0x0400

LEAVE_SRC

Encode::LEAVE_SRC

Если бит Encode::LEAVE_SRC не установлен, но CHECK установлен, то исходная строка для encode() или decode() будет перезаписана на месте. Если вас это не интересует, то побитовое ИЛИ её с маской.

coderef для CHECK

Начиная с Encode версии 2.12, CHECK также может быть ссылкой на процедуру, которая принимает значение порядкового номера недопустимого символа как аргумент и возвращает октеты, представляющие замещающий символ. Например:

$ascii = encode("ascii", $utf8, sub{ sprintf "<U+%04X>", shift });

Действует как FB_PERLQQ но используется U+XXXX вместо \x{XXXX}.

Падение для decode должно возвращать декодированную строку (последовательность символов) и принимает список значений порядкового номера в качестве аргументов. Например, если вы хотите декодировать октеты как UTF-8 и использовать ISO-8859-15 в качестве падения для байтов, которые не являются допустимым UTF-8, вы можете написать

$str = decode 'UTF-8', $octets, sub {
    my $tmp = join '', map chr, @_;
    return decode 'ISO-8859-15', $tmp;
};

Определение кодировок

Чтобы определить новую кодировку, используйте:

use Encode qw(define_encoding);
define_encoding($object, CANONICAL_NAME [, alias...]);

CANONICAL_NAME будет связан с $object. Объект должен предоставить интерфейс, описанный в Encode::Encoding. Если предоставлено более двух аргументов, дополнительные аргументы рассматриваются как псевдонимы для $object.

Подробности см. в Encode::Encoding.

Флаг UTF8

До появления поддержки Юникода в Perl оператор eq просто сравнивал строки, представленные двумя скалярами. Начиная с Perl 5.8, eq сравнивает две строки с одновременным учётом флага UTF8. Чтобы объяснить, почему мы это сделали, я процитирую со страницы 402 книги Programming Perl, 3rd ed.

Цель #1:

Старые программы, ориентированные на байты, не должны спонтанно выходить из строя при работе со старыми данными, ориентированными на байты.

Цель #2:

Старые программы, ориентированные на байты, должны автоматически начать работать с новыми данными, ориентированными на символы, при необходимости.

Цель #3:

Программы должны работать так же быстро в новом режиме, ориентированном на символы, как и в старом режиме, ориентированном на байты.

Цель #4:

Perl должен оставаться одним языком, а не разделять его на Perl, ориентированный на байты, и Perl, ориентированный на символы.

Когда Programming Perl, 3rd ed. был написан, ещё не родился Perl 5.6.0, многие функции, описанные в книге, долгое время оставались нереализованными. Perl 5.8 исправил большую часть этого, и появление флага UTF8 — одно из них. Можно представить, что существуют два принципиально различных типа строк и строковых операций в Perl: один — это байтовый режим, когда внутренний флаг UTF8 выключен, и другой — это символьный режим, когда внутренний флаг UTF8 включён.

Этот флаг UTF8 не отображается в скриптах Perl, точно так же, как вы не можете (или, точнее, вам не нужно) видеть, содержит ли скаляр строку, целое число или число с плавающей запятой. Но вы всё ещё можете просматривать и изменять их, если захотите. См. следующий раздел.

Вмешательство во внутреннюю работу Perl

Следующий API использует части внутренней реализации Perl в текущей версии. Таким образом, он эффективный, но может измениться в будущих релизах.

is_utf8

is_utf8(STRING [, CHECK])

[ВНУТРЕННИЙ] Проверяет, включён ли флаг UTF8 в СТРОКЕ. Если CHECK равно true, также проверяет, содержит ли СТРОКА правильно сформированный UTF-8. Возвращает true при успехе, false в противном случае.

Как правило, требуется только для отладки и тестирования. Не используйте этот флаг в качестве маркера для различения символьных и двоичных данных; это следует определять для каждой переменной при написании кода.

ПРЕДУПРЕЖДЕНИЕ: Если для STRING установлен флаг UTF8, это НЕ означает, что STRING закодирован в UTF-8, и наоборот.

Начиная с Perl 5.8.1, в utf8 также есть функция utf8::is_utf8.

_utf8_on

_utf8_on(STRING)

[ВНУТРЕННЕЕ] Устанавливает внутренний флаг UTF8 для STRING. STRING не проверяется на корректность кодировки UTF-8. Не используйте эту функцию, если вы абсолютно уверены, что STRING содержит только корректные данные UTF-8. Возвращает предыдущее состояние флага UTF8 (поэтому не рассматривайте значение возврата как указание на успех или неудачу), или undef если STRING не является строкой.

ПРИМЕЧАНИЕ: По соображениям безопасности эта функция не работает со значениями, помеченными как ненадёжные.

_utf8_off

_utf8_off(STRING)

[ВНУТРЕННЕЕ] Сбрасывает внутренний флаг UTF8 для STRING. Не используйте эту функцию без необходимости. Возвращает предыдущее состояние флага UTF8 или undef если STRING не является строкой. Не интерпретируйте значение возврата как указание на успех или неудачу, потому что это не так: оно только отражает предыдущее значение.

ПРИМЕЧАНИЕ: По соображениям безопасности эта функция не работает со значениями, помеченными как ненадёжные.

UTF-8 vs. utf8 vs. UTF8

....We now view strings not as sequences of bytes, but as sequences
of numbers in the range 0 .. 2**32-1 (or in the case of 64-bit
computers, 0 .. 2**64-1) -- Programming Perl, 3rd ed.

Исторически это было представлением UTF-8 в Perl, так как именно так UTF-8 был впервые задуман Кеном Томпсоном при его изобретении. Однако благодаря последующим изменениям соответствующих стандартов официальный UTF-8 теперь более строг. Например, его диапазон значительно уже (0 .. 0x10_FFFF для покрытия только 21 бита вместо 32 или 64 бит), и некоторые последовательности запрещены, такие как те, которые используются в суррогатных парах, 31 код без символа 0xFDD0 .. 0xFDEF, две последние точки кода в любом плане (0xXX_FFFE и 0xXX_FFFF), все кодировки, не являющиеся кратчайшими, и т. д.

Прежний стандарт, при котором Perl всегда использовал свободную интерпретацию UTF-8, теперь отменён:

From: Larry Wall <larry@wall.org>
Date: December 04, 2004 11:51:58 JST
To: perl-unicode@perl.org
Subject: Re: Make Encode.pm support the real UTF-8
Message-Id: <20041204025158.GA28754@wall.org>

On Fri, Dec 03, 2004 at 10:12:12PM +0000, Tim Bunce wrote:
: I've no problem with 'utf8' being perl's unrestricted uft8 encoding,
: but "UTF-8" is the name of the standard and should give the
: corresponding behaviour.

For what it's worth, that's how I've always kept them straight in my
head.

Also for what it's worth, Perl 6 will mostly default to strict but
make it easy to switch back to lax.

Larry

Понятен ли смысл? Начиная с Perl 5.8.7, «UTF-8» означает UTF-8 в его современном понимании, то есть консервативном, строгом и учитывающем безопасность, в то время как «utf8» означает UTF-8 в его прежнем понимании, то есть более свободном и менее строгом. Encode версия 2.10 или выше таким образом понимает это тонкое, но критически важное различие между "UTF-8" и "utf8".

encode("utf8",  "\x{FFFF_FFFF}", 1); # okay
encode("UTF-8", "\x{FFFF_FFFF}", 1); # croaks

Это различие также важно для декодирования. В следующем примере $s хранит символ U+200000, который превышает допустимый диапазон UTF-8. $s таким образом хранит недопустимый код Юникода:

$s = decode("utf8", "\xf8\x88\x80\x80\x80");

"UTF-8", в свою очередь, либо приведёт вход к какому-либо допустимому значению:

$s = decode("UTF-8", "\xf8\x88\x80\x80\x80"); # U+FFFD

.. или выдаст ошибку:

decode("UTF-8", "\xf8\x88\x80\x80\x80", FB_CROAK|LEAVE_SRC);

В модуле Encode, "UTF-8" фактически является каноническим именем для "utf-8-strict". Этот дефис между "UTF" и "8" критически важен; без него Encode принимает "свободный" и (возможно, излишне) терпимый подход:

find_encoding("UTF-8")->name # is 'utf-8-strict'
find_encoding("utf-8")->name # ditto. names are case insensitive
find_encoding("utf_8")->name # ditto. "_" are treated as "-"
find_encoding("UTF8")->name  # is 'utf8'.

Внутренний флаг UTF8 в Perl называется «UTF8» без дефиса. Он указывает, закодирована ли строка внутри как «utf8» также без дефиса.

СПРАВКА

Encode::Encoding, Encode::Supported, Encode::PerlIO, encoding, perlebcdic, "open" в perlfunc, perlunicode, perluniintro, perlunifaq, perlunitut, utf8, список рассылки Perl Unicode http://lists.perl.org/list/perl-unicode.html

СОХРАНИТЕЛЬ

Этот проект был инициирован покойным Ником Ин-Симмонсом и позже поддерживался Даном Когаем <dankogai@cpan.org>. Полный список участников см. в файле AUTHORS. Для любых вопросов отправляйте сообщения на адрес <perl-unicode@perl.org>, чтобы мы могли все обменяться информацией.

Хотя Дан Когай сохраняет авторские права как ответственный за поддержку, заслуга принадлежит всем участникам. Полный список людей, внесших код в проект, см. в файле AUTHORS.

АВТОРСКИЕ ПРАВА

Copyright 2002-2014 Дан Когай <dankogai@cpan.org>.

Эта библиотека является свободным программным обеспечением; вы можете распространять и/или изменять её на тех же условиях, что и сам Perl.

© 1993–2023 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.38.0/Encode

Spec-Zone.ru

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