Java --如何对unicode专用字符进行反转义?

cgvd09ve  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(195)

我有一个程序,它读取未转义的unicode字符串列表(u/XXXX),并将它们转换成编码的unicode字符,将该版本写入终端和文本文件。
我使用org.apache.commons.text.StringEscapeUtils.unescapeJava(String)来处理转义的unicode点的反转义。(来自Apache Commons Text库。)
我引用这些unicode条目来获取我的私有字符:https://jrgraphix.net/r/Unicode/E000-F8FF(我用上面^所示的十六进制数字来准备u/
下面是输出的示例:如果你把它粘贴到上面网站的ctrlF框中,你会看到它指向E022

现在,这是我的问题,通过扩展我的问题:

它不工作。由于某种原因,它不输出字符本身,而是它只是输出一个通用的问号,不代表私人使用的字符的问题。如果有人能帮助我这将是非常感谢。
到目前为止,我还没有运气。

rekjcdws

rekjcdws1#

TL;医生

  • 在Unicode十六进制的输入字符串中使用正确的Java语法:\uXXXX
  • 如果您没有为该码位号提供字形的字体,您的操作系统将通过显示一个空框、问号或一些类似的后备替换来指示缺少。

要获得官方认可的红心勋章:

org.apache.commons.text.StringEscapeUtils.unescapeJava( "\\" + "u2764" + "\\" + "uFE0F" )  // Simulating some textual input of Java-syntax escaped Unicode code point numbers in hexadecimal.

❤️

示例代码

您没有显示确切的代码。但您的问题提到u/XXXX,这是不正确的。在Java中,Unicode十六进制的正确语法是\uXXXX
您可以通过询问代码点来验证十六进制文本,如下所示。
下面是一些示例代码。

System.out.println( "Demo of Private Use Area" );

String input = "\\" + "uE022";
String output = org.apache.commons.text.StringEscapeUtils.unescapeJava( input );
int codePoint = output.codePointAt( 0 );
String name = Character.getName( codePoint );

转储到控制台。

System.out.println( "input = " + input );
System.out.println( "output = " + output );
System.out.println( "codePoint = " + codePoint + " (we expect 57378 for \\uE022)." );
System.out.println( "Name = " + name );

运行时:

Demo of Private Use Area
input = \uE022
output = 
codePoint = 57378 (we expect 57378 for \uE022).
Name = PRIVATE USE AREA E022

红心表情
如果你真的想要一颗红心,Unicode确实定义了一个表情符号。
但访问这个表情符号需要 * 两个 * 码位。1993年的Unicode 1.1将"沉重的黑心"定义为小数点10,084(U +2764)。后来的Unicode版本在2015年增加了Emoji 1.0的定义,将HEAVY BLACK HEARTVARIATION SELECTOR-16组合在小数点65,039(U + FEOF),增加了红心的定义。
请参阅Unicode Consortium网站上Full Emoji Listred heart行。但是,在我看来,该行似乎是不正确的,因为它没有提到所需的U+FE0F码点。

// HEAVY BLACK HEART + VARIATION SELECTOR-16 = Red Heart.
String input = "\\" + "u2764" + "\\" + "uFE0F";
String output = org.apache.commons.text.StringEscapeUtils.unescapeJava( input );

❤️
完整示例代码:

System.out.println( "Demo of Red Heart" );

// HEAVY BLACK HEART + VARIATION SELECTOR-16 = Red Heart.
String input = "\\" + "u2764" + "\\" + "uFE0F";
String output = org.apache.commons.text.StringEscapeUtils.unescapeJava( input );

System.out.println( "input = " + input );
System.out.println( "output = " + output );

output.codePoints().forEachOrdered( ( int codePoint ) -> {
    String message =
            "Code point decimal " + codePoint
                    + " = hex " + Integer.toHexString( codePoint )
                    + " = name " + Character.getName( codePoint );
    System.out.println( message );
} );

运行时:

Demo of Red Heart
input = \u2764\uFE0F
output = ❤️
Code point decimal 10084 = hex 2764 = name HEAVY BLACK HEART
Code point decimal 65039 = hex fe0f = name VARIATION SELECTOR-16

PUA没有正式分配的字符

根据定义,Private Use Area (PUA)没有由Unicode Consortium分配的字符。Unicode协会承诺,该范围内的所有code point数字永远不会被正式分配任何字符。
这样,我们就可以自由地创建一种字体,将任何类型的glyph分配给这些代码点中的任何一个。
您可能希望在代码点E022创建一个带有红心卡通的字体。同时,我可能会选择创建一个带有凤头鹦鹉图案的字体。某个叫Bob的人在E022创建了一个带有Microlino汽车图片的字体。我们所有人,你,我和Bob,我们都很高兴知道我们的自定义字体将永远不会被将来官方认可的字符在该代码点上践踏。
如果爱丽丝喜欢你的红心,并想使用它,她需要获得你的字体副本。她需要在她的计算机上安装该字体。她需要:

  • 确保没有任何Enter字体在代码点E022、* 或 * 处提供字形
  • 使用一个应用程序,让她指定使用您的字体,而不是任何其他字体,也可能碰巧提供了一个字形在E022。

👉 如果Alice在E022处根本没有安装具有字形的字体,则她的计算机的操作系统将退回到显示某种替代字形,诸如空框或问号或没有指示缺少字形的内容。
Unicode中定义的三种PUA已经被证明是相当流行的。人们使用它们来为不符合Unicode联盟要求的字符创建字体,从而阻止这些字符被考虑将来纳入Unicode。例如,虚构语言,如《星际迷航》中的Klingon或小说中的精灵语言。
这种流行促使Unicode联盟以外的志愿者设计了PUA码点的公共注册表,试图避免不同字体之间在特定码点上的冲突。

相关问题