java - 如何从变量中的 id 获取 unicode 字符?
问题描述
我正在尝试使用每个 Unicode 变量生成一个文件。我已经能够将 unicode 提升到 U+FFFF,但是我需要将它提升到 U+231F4。我试过寻找答案,但是当符号 id 在变量中而不是仅仅输入时,它们都不起作用。
现在,我有这个:
for (int i = 0; i < 143860; i++) {
System.out.println((char)i);
}
它不是上升到 U+231F4,而是上升到 U+FFFF,并在它正在打印的文档中循环。如何使它转到更高的 Unicode ID?
解决方案
[ OP 说“我需要把它升级到 U+231F4 ”,我回答了这个问题。但他们的意思是他们想要打印 Unicode 定义的 143,859 个代码点。看另一个答案。我现在不能删除它,因为它已被接受。]
Java 字符串不是由 Unicode 代码点构成,而是由 UTF-16 代码单元构成。对于 U+FFFF 以上的 Unicode 代码点,您需要使用代理对。例如,
U+0 ⇒ 0x0000 ⎫
U+1 ⇒ 0x0001 ⎪
⋮ ⎬ Character in the BMP result
U+D7FE ⇒ 0xD7FE ⎪ in a single UTF-16 code unit.
U+D7FF ⇒ 0xD7FF ⎭
U+D800 ⇒ ------ ⎫
U+D801 ⇒ ------ ⎪
⋮ ⎬ Can't be encoded using UTF-16.
U+DFFE ⇒ ------ ⎪ Illegal for interchange for this reason.
U+DFFF ⇒ ------ ⎭
U+E000 ⇒ 0xE000 ⎫
U+E001 ⇒ 0xE001 ⎪
⋮ ⎬ Character in the BMP result
U+FFFE ⇒ 0xFFFE ⎪ in a single UTF-16 code unit.
U+FFFF ⇒ 0xFFFF ⎭
U+10000 ⇒ 0xD800, 0xDC00 ⎫
U+10001 ⇒ 0xD800, 0xDC01 ⎪
⋮ ⎬ Those outside result in two.
U+231F2 ⇒ 0xD84C, 0xDDF2 ⎪
U+231F3 ⇒ 0xD84C, 0xDDF3 ⎭
U+231F4 ⇒ 0xD84C, 0xDDF4 ⎫
U+231F5 ⇒ 0xD84C, 0xDDF5 ⎪
⋮ ⎬ We don't care about these.
U+10FFFE ⇒ 0xDBFF, 0xDFFE ⎪
U+10FFFF ⇒ 0xDBFF, 0xDFFF ⎭
有关代理对的详细信息,您可以查阅UTF-16的 Wikipedia 页面。
解决方案1:printf %c
这些细节无关紧要,因为我们可以使用printf %c
将 Unicode 代码点编码为 UTF-16 代码单元。(感谢@VGR。)
for (int cp=0; cp<0x231F4; ++cp) {
if (cp < 0xD800 || cp >= 0xE000) {
System.out.printf("%c%n", cp);
}
}
优化:
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
for (int cp=0x10000; cp<0x231F4; ++cp) {
System.out.printf("%c%n", cp);
}
解决方案2:Character.toChars
或者,我们可以使用Character.toChars(codePoint)
生成一个char[]
包含 UTF-16 代码单元的 Unicode 代码点。
for (int cp=0; cp<0x231F4; ++cp) {
if (cp < 0xD800 || cp >= 0xE000) {
System.out.println(Character.toChars(cp));
}
}
优化:
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
for (int cp=0x10000; cp<0x231F4; ++cp) {
System.out.println(Character.toChars(cp));
}
我相信上面仍然会创建很多数组。自己实现转换可以避免这种情况,因此应该更快。
// Up to but excluding U+231F4 ⇒ 0xD84C, 0xDDF4
for (int cp=0; cp<0xD800; ++cp) {
System.out.println((char)cp);
}
for (int cp=0xE000; cp<0x10000; ++cp) {
System.out.println((char)cp);
}
char pair[2];
for (int hisurro=0xD800; hisurro<0xD84C; ++hisurro)
pair[0] = (char)hisurro;
for (int losurro=0xDC00; losurro<0xE000; ++losurro)
pair[1] = (char)losurro;
System.out.println(pair);
}
}
pair[0] = 0xD84C;
for (int losurro=0xDC00; losurro<0xDDF4; ++losurro)
pair[1] = (char)losurro;
System.out.println(pair);
}
请注意,结果在您的终端中不会完全可读。输出包括不可打印字符(例如控制字符)、标记(与其他字符组合)、未分配的代码点、私人使用的代码点等。
推荐阅读
- three.js - ThreeJS 开门动画
- java - 使用 POI 访问旧 excel .xls 文件的单元格
- amp-html - 如何使用 AMP-Carousel 加载(更改)图像 src?(用于电子邮件的 AMP)
- javascript - GET 请求没有显示错误
- dockerfile - 将 Dockerfile 中的 jboss/base-jdk 8 更新为 11
- json - 如果您的值为空,有一种方法可以将属性删除到 sdt?
- c - 谁能告诉我这种数据类型有多少字节?
- powershell - 在 Powershell 中创建和比较哈希表
- c# - 在 ASP.NET-Core 2.2 中检索给定类型的声明集合
- html - 网格布局中的中心锚标记