将unicode符号转换为其代码

时间:2015-10-24 15:46:43

标签: java unicode

我有以下XML文件,其中包含表情符号:http://pastebin.com/8f0GeE96

现在,我想要的是将每个unicode字符转换为它的代码(作为字符串)。我已为此原因编写了以下代码。问题是我得到了很多dup(即d83d),这让我觉得我的解析出了问题。对此有何解释?

public static void main(String[] args) {

        File file = new File("c:\\EmojisList.plist.txt");

        try {
            BufferedReader in = new BufferedReader(
                       new InputStreamReader(new FileInputStream(file), "UTF8"));

            String str;
            while ((str = in.readLine()) != null) { 
                if(str.trim().startsWith("<string>"))
                {
                    int emoji_pos = str.indexOf('>') + 1;
                    char emoji_char = str.charAt(emoji_pos);
                    String emoji_code_str = Integer.toHexString(emoji_char);

                    System.out.println(emoji_code_str);
                }

            }

            in.close();


        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

1 个答案:

答案 0 :(得分:1)

Unicode标准以一系列字符开始,其中16位(两个字节)就足够了。

但是,添加了越来越多的脚本和符号,而现在,您无法用16位表示所有字符。代码点的合法范围是从U + 0到U + 10FFFF。

不幸的是,这不适合Java char,它只有16位,能够表示0到FFFF的值。

大多数常见的西方语言都没有这个问题 - 包括口音,俄语,阿拉伯语,希伯来语等在内的拉丁语范围都在16位范围内。即使是常见的中文和日文字符都在此范围内。

但是大多数表情符号实际上都在&#34;扩展&#34;范围,在unicode&#34;其他符号和象形文字&#34;和#34;表情符号&#34;块,范围从U + 1F300到U + 1F5FF,从U + 1F600到U + 1F67F。

此范围内的字符使用UTF-16编码以字符串表示,该编码基本上为每个此类字符使用两个char值。因此,如果角色的代码点(其官方unicode值)在U + 10000到U + 10FFFF范围内,则有两个{​​{1}}值,其中一个来自U + D800范围通过U + DB7F(&#34;高代理&#34;),以及范围U + DC00到U + DFFF(&#34;低代理&#34;)中的一个用于表示它。

因此,当您在程序中读取char的值时,实际上只读取实际字符的前半部分。事实上,所有的表情符号都是在表情符号&#34;范围具有U + D83D的高代理特征。

因此,要获取表情符号的实际Unicode代码点,您需要将UTF-16表示转换为实际的charAt(emoji_pos)值。 int是不够的。您可以使用charString类中可用的方法来执行此操作。

在这种情况下,您只需使用codePointAt方法,而不是使用Character

所以,而不是

charAt

使用:

char emoji_char = str.charAt(emoji_pos);

有关详细信息,请阅读Unicode Consortium网站上的UTF FAQ

注意:Java编码约定是变量,字段方法名称应该是较低的驼峰情况:第一个单词以小写字母开头,其他单词以大写字母开头,没有下划线。因此,变量名称应为int emojiCodePoint = str.codePoint(emojiPos); ,而不是emojiCodePoint。下划线仅在常量名称中可接受,这些名称全部为大写(例如emoji_code_point)。