Spec-Zone.ru › Perl 5.36

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 может быть либо каноническим именем, либо псевдонимом. Имена и псевдонимы кодировок см. в разделе "Определение псевдонимов". Для проверки см. "Обработка поврежденных данных".

ПРЕДУПРЕЖДЕНИЕ: входной скаляр 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 в кодировку Microsoft CP1250:

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 Character Set

Каноническое имя заданной кодировки необязательно совпадает с реестром имен наборов символов 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)
режим HTML charref (CHECK = Encode::FB_HTMLCREF)
режим XML charref (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, но вместо \x{XXXX} используется U+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, 3-е изд.

Цель #1:

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

Цель #2:

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

Цель #3:

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

Цель #4:

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

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

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

Работа с внутренними компонентами Perl

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

is_utf8

is_utf8(STRING [, CHECK])

[ВНУТРЕННЕЕ] Проверяет, включен ли флаг UTF8 в STRING. Если CHECK истинно, также проверяет, содержит ли STRING корректный 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 не является строкой.

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

_utf8_off

_utf8_off(STRING)

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

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

UTF-8 против utf8 против 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.

Исторически это было представлением Perl о UTF-8, так как именно так 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 таким образом хранит недопустимый код Unicode:

$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.

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

Авторские права 2002-2014 Дана Когаи <dankogai@cpan.org>.

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

© 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/Encode

Spec-Zone.ru

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