Как ввести Unicode не BMP (шестнадцатеричный с более чем 4 символами) в качестве ввода в Mathematica
Описание проблемы: использование Mathematica "\:nnnn"
в качестве синтаксиса для ввода Unicode. Например, если мы входим "\:6c34"
, мы получаем "水"
("вода" по-китайски). Но что, если кто-то хочет войти "\:1f618"
(лицо целует). Когда я попробовал это, я получил "ὡ8"
не "a face throwing a kiss"
, Итак, Mathematica оценивает "\:1f61"
прежде чем я вошел "8"
,
Вопрос: Как мы можем отложить эту оценку или как мы можем ввести любой ввод Unicode вообще (как для шестнадцатеричного с более чем 4 символами)?
Программно-аппаратная платформа: я использую Mathematica 8 на Intel Mac. Я попробовал обе версии командной строки Mathematica и ноутбука Mathematica, они ведут себя одинаково.
Спасибо.
Размышления: Unicode - это расширяемый стандарт, и он может расти (и он действительно растет:)). Программные системы, которые реализуют этот стандарт, могут реализовывать только часть этого стандарта, чтобы быть действительными и полезными (8-битное, 16-битное или 32-битное кодирование). Во-первых, как пользователь определенного программного пакета, не следует исходить из того, что, как только программное обеспечение говорит, что оно поддерживает Unicode, оно поддерживает универсальный набор Unicode.
2 ответа
Краткий ответ: Вы не можете сделать это, потому что Mathematica не поддерживает эти символы должным образом. Смотрите в конце поста для некоторых обходных путей.
Просто чтобы прояснить некоторые вещи:
Нет необходимости в 32-битной кодировке для обработки более ~65000 символов Юникода. Наиболее распространенными кодировками, используемыми для Unicode, UTF-8 и UTF-16, являются многобайтовые кодировки, что означает, что для представления символов используется переменное число байтов. UTF-16 может использовать 2 или 4 байта для представления символа. Ядро Mathematica будет интерпретировать каждую 2-байтовую последовательность как один символ в строке, что иногда приводит к появлению некоторых недопустимых символов (при обнаружении 4-байтовой последовательности). Это можно считать ошибкой. Передний конец довольно капризен в отношении того, как он обрабатывает 4-байтовые последовательности, что, безусловно, является ошибкой.
Ограниченное решение
Работая строго в ядре (например, читая данные Unicode из файла), я иногда использую эту функцию в качестве обходного пути, чтобы получить фактическую кодовую точку Unicode для 2-значных (4-байтовых) последовательностей UTF-16:
toCodePoint[{a_, b_}] /; 16^^d800 <= a <= 16^^dbff && 16^^dc00 <= b <= 16^^dfff := (a - 16^^d800)*2^10 + (b - 16^^dc00) + 16^4
Ты можешь использовать
Split[ToCharacterCode[str], If[16^^d800 <= # <= 16^^dbff, True] &]
правильно разделить строку UTF-16 на символы Юникода (длина-один или длина-два, в зависимости от символа).
Это уродливый и неудобный обходной путь, и он не позволит вам отображать что-либо из этих символов во внешнем интерфейсе, если вы не придумаете для этого также хак, например, импортируете эталонные изображения глифов из unicode.org (в хотя бы для CJK они есть).
Смотрите также
Смотрите мой предыдущий вопрос на ту же тему: Чтение текстового файла в кодировке UTF-8 в Mathematica
Если вы собираетесь работать с китайским языком, вы можете столкнуться и с этой проблемой: заставить интерфейс Mathematica подчиняться опции FontFamily
Согласно этой странице в Mathematica 8 помогают:
Mathematica supports both 8- and 16-bit raw character encodings.
Предположительно они говорят, что не поддерживают 32-битные кодировки, необходимые для поддержки желаемого персонажа.
В качестве еще одного доказательства (при отсутствии четкого указания в документации), список поддерживаемых кодировок на той же странице не имеет 32-битных кодировок. 32-битные кодировки, по-видимому, поддерживаются только в MathLink. Я предполагаю, что не было достаточного пользовательского спроса.