Как получить символ по имени (unicode) в Java?

как найти символ или кодовую точку int в Java, используя его имя Unicode?

, если
Character.getName('u00e4')

возвращает "LATIN SMALL LETTER A WITH DIAERESIS", Как выполнить обратную операцию (т. е. иди от "LATIN SMALL LETTER A WITH DIAERESIS" to 'u00e4') использование "простой" Java?

изменить: прекратить поток комментариев, что я хочу или не хочу!--14-->, вот что я бы сделал в Python:

"N{LATIN SMALL LETTER A WITH DIAERESIS}" # this gives me what I want as a literal

unicodedata.lookup("LATIN SMALL LETTER A WITH DIAERESIS") # a dynamic version

теперь вопрос: сделайте то же самое на Java.

и, кстати,, Я не хочу "печатать Unicode escapes" - на самом деле получить hex для char легко, но я хочу, чтобы char носил данное имя.

другими словами я хочу сделать обратное тому, что Character.getName(int) делает.

2 ответов


на ICU4J библиотека может помочь вам здесь. У него есть класс UCharacter с getCharFromName и другие связанные методы, которые могут отображать из различных типов строк имен символов обратно в int кодовые точки, которые они представляют.

однако, если вы работаете с жестко закодированными именами символов (т. е. цитируемыми строковыми литералами в исходном коде), то было бы намного эффективнее сделать перевод один раз - используйте \u escape в исходном коде и добавить при необходимости комментируйте с полным именем - вместо того, чтобы каждый раз выполнять разбор таблиц имен во время выполнения. Если имена символов поступают из чтения файла или аналогичного, то, очевидно, вам придется конвертировать во время выполнения.


Ну, глядя на исходный код Character.class:

public static String getName(int codePoint) {
    if (!isValidCodePoint(codePoint)) {
        throw new IllegalArgumentException();
    }
    String name = CharacterName.get(codePoint);
    if (name != null)
        return name;
    ...
}

CharacterName - это класс package-private, который лениво инициализирует SoftReference<byte[]> пул имен символов (я думаю). Одна строка, в частности, представляет интерес, хотя и похоронена внутри ряда различных конструкторов входного потока:

private static synchronized byte[] initNamePool() {
    ...
        return getClass().getResourceAsStream("uniName.dat");
    ...
}

теперь я кое-что раскопал, и по какой-то причине это uniName.dat кажется, не существует в источнике OpenJDK. Я нашел uniName.dat -- как часть моего TeX Живое распространение, как ни странно. Открытие его в шестнадцатеричном редакторе показывает беспорядок байтов - поэтому содержимое каким-то образом кодируется. Как, понятия не имею. я еще раз взглянуть на исходный код, но это может занять некоторое время, чтобы расшифровать, если я могу понять это на всех.

кроме того, отладчик в моей копии Eclipse кажется сломанным (по той или иной причине не может разрешить переменные), поэтому я не могу проверить входной поток, чтобы попытаться увидеть, где он читает от.

короче говоря, не кажется, что вы можете сделать это в родной Java, если вы не чувствуете, как копировать-вставить код пула имен из CharacterName, или сворачивание собственного кода, который расшифровывает этот файл (при условии, что вы можете его найти)


Edit: Найдено uniName.dat! На моей машине, расположенной в resources.jar в установке Java. Все еще куча байтов. Таким образом, вы можете либо разобрать этот файл самостоятельно (не очень весело, включает в себя много бит twiddling), или использовать библиотеку (рекомендуется выше). Так если вы ограничены родной Java, вы можете взглянуть на CharacterName класс и посмотреть, если вы можете сделать что-то в HashMap<String, Character>.