首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Java中使用其(unicode)名称来获取字符?我需要Character.getName的反向(Int codePoint)

如何在Java中使用其(unicode)名称来获取字符?我需要Character.getName的反向(Int codePoint)
EN

Stack Overflow用户
提问于 2014-05-15 07:02:05
回答 3查看 2.7K关注 0票数 14

如何使用Unicode名称在Java中查找字符或int代码点?

例如,如果

代码语言:javascript
复制
Character.getName('\u00e4')

返回"LATIN SMALL LETTER A WITH DIAERESIS",如何使用“普通”Java执行反向操作(即从"LATIN SMALL LETTER A WITH DIAERESIS"'\u00e4')?

编辑:为了停止我想要或不想要的评论的洪流,下面是我在中应该做的事情:

代码语言:javascript
复制
"\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中做同样的事情。

而且,BTW,我不想“打印unicode转义符”--实际上,字符的十六进制很容易得到,但是我想要一个带有名字的字符。

,换句话说,,我想做Character.getName(int)所做的相反的事情。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-18 05:12:15

对于JDK 9和更高版本,使用静态方法Character.codePointOf(String name)是最简单的方法:

公共静态int代码点​(字符串名) 返回由给定Unicode字符名指定的Unicode字符的代码点值。

这适用于所有的Uniocde字符,而不仅仅是那些基本的多语言平面上的字符。例如,在Java 12上运行此代码.

代码语言:javascript
复制
String s1 = "LATIN SMALL LETTER A WITH DIAERESIS";
int cp1 = Character.codePointOf(s1);
System.out.println("Unicode name \"" + Character.getName(cp1) + "\" => code point " + cp1 + " => character " + Character.toString(cp1));

String s2 = "EYES";
int cp2 = Character.codePointOf(s2);
System.out.println("Unicode name \"" + Character.getName(cp2) + "\" => code point " + cp2 + " => character " + Character.toString(cp2));

String s3 = "DNA Double Helix"; // Only works with JDK12 and later. Otherwise java.lang.IllegalArgumentException is thrown.
int cp3 = Character.codePointOf(s3);
System.out.println("Unicode name \"" + Character.getName(cp3) + "\" => code point " + cp3 + " => character " + Character.toString(cp3));

...produces输出..。

代码语言:javascript
复制
Unicode name "LATIN SMALL LETTER A WITH DIAERESIS" => code point 228 => character ä
Unicode name "EYES" => code point 128064 => character 
Unicode name "DNA DOUBLE HELIX" => code point 129516 => character 

总结一下这些转变:

  • 对于代码点=> Unicode名称,请使用Character.getName(codepoint)
  • 对于代码点=>字符表示,请使用Character.toString(codepoint)
  • 对于Unicode名称=>代码点,请使用Character.codePointOf(name)
  • 对于Unicode名称=>字符表示,目前不存在JDK方法。相反,使用Unicode名称的代码点间接地这样做,如上面所示。例如:Character.toString(Character.codePointOf("LATIN SMALL LETTER A WITH DIAERESIS"));

备注:

  • 确保所使用的JDK版本支持指定的Unicode名称。例如,Unicode名称为"DNA Double Helix“的字符被添加到Unicode 11中,它仅受JDK版本>= 12的支持。如果使用早期的JDK版本运行,则在调用Character.codePointOf("DNA Double Helix")时将得到一个IllegalArgumentException
  • 如果用白色方块代替Unicode字符,则尝试更改字体(例如,Segoe用于呈现Emoji字符)。
票数 4
EN

Stack Overflow用户

发布于 2014-05-15 08:03:07

ICU4J库可以在这里帮助您。它有一个带有UCharacter和其他相关方法的类,这些方法可以从各种类型的字符名字符串映射回它们表示的int代码点。

但是,如果您正在使用硬编码字符名(即源代码中引用的字符串文字),那么一次转换(在源代码中使用\u转义并在必要时添加带有全名的注释)将更加有效,而不是每次运行时都需要解析名称表的成本。如果字符名来自读取文件或类似的文件,那么显然您必须在运行时进行转换。

票数 5
EN

Stack Overflow用户

发布于 2018-11-11 22:31:51

我希望这个仅依赖于“普通”Java的类将对某些人有用。它利用了延迟填充的查找表,这些查找表可以通过reset(false)调用随时清除,以释放内存(如果需要,可以自动填充表并再次使用它)。如果要查找的字符位于较低的Unicode块(通常是这样),则此表的填充时间几乎不明显。我添加了可选的可能性,通过调用reset(true)预先填充整个表。

还请注意,在Unicode名称冲突U+0007之间有已知的U+1F514。Java的Character.getName()仍然返回前者的“贝尔”。所呈现的类试图至少在反向操作中修复这个问题,返回分配给它的已批准的唯一名称“警报”的U+0007

代码语言:javascript
复制
import java.util.Map;
import java.util.HashMap;

public class UnicodeTable {
    public static final char INVALID_CHAR = '\uFFFF';
    private static final Map<String, Integer> charMap = new HashMap<>();
    private static boolean incomplete;
    private static int lastLookup;

    static {
        reset(false);
    }

    public static int getCodePoint(String name) {
        Integer cp = charMap.get(name);
        if (cp == null && incomplete) {
            while (++lastLookup <= Character.MAX_CODE_POINT) {
                String uName = Character.getName(lastLookup);
                if (uName != null) {
                    charMap.put(uName, lastLookup);
                    if (uName.equals(name))
                        return lastLookup;
                }
            }
            incomplete = false;
        }
        return cp == null ? INVALID_CHAR : cp;
    }

    public static char getChar(String name) {
        int cp = getCodePoint(name);
        return Character.isBmpCodePoint(cp) ? (char)cp : INVALID_CHAR;
    }

    private static final int ALERT = 0x000007;
    private static final int BELL = 0x01F514;

    public static void reset(boolean fillUp) {
        if (!fillUp) {
            charMap.clear();
            incomplete = true;
            lastLookup = Character.MIN_CODE_POINT - 1;
            charMap.put("ALERT", ALERT);
            String bName = Character.getName(BELL);
            if (bName.equals(Character.getName(ALERT))) {
                getCodePoint(bName);
                charMap.put(bName, BELL);
            }
        } else if (incomplete) {
            while (++lastLookup <= Character.MAX_CODE_POINT) {
                String uName = Character.getName(lastLookup);
                if (uName != null)
                    charMap.put(uName, lastLookup);
            }
            incomplete = false;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23671346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档