关于unicode:Unicode-与编程语言

45次阅读

共计 2046 个字符,预计需要花费 6 分钟才能阅读完成。

编程语言中的 Unicode

因为 Unicode 能够给世界上大部分字符编码,因而大部分编程语言外部,都是应用 Unicode 来解决字符的。例如在 Java 中定义一个字符 char c = '中',这个字符理论是应用两个字节在内存中存储着他的 UTF-16 编码。所以如果将这个字符强转成整型 int i = (int) c,失去的后果 20013 (0x4E2D),就是 在 Unicode 中的 Code Point 值。

这个说法不齐全精确,因为大部分编程语言定义的时候,Unicode 还没有辅助立体,所以个别都是固定的用两个字节来存储一个字符。

在有了辅助立体当前,辅助立体的字符,会被 UTF-16 编码成两个 Code Unit,须要 4 个字节来存储。而编程语言为了兼容性,不太可能将原有的 char 类型长度改为 4 个字节。所以就有可能须要用两个 char 来存储一个理论的字符。而原有的获取字符串长度的 API,理论获取到的是字符串中 Code Unit 的个数,不是理论字符的个数。获取某个地位字符的 API 也是同理,获取到的可能是一对 Code Unit 中的一个。因而须要应用编程语言提供的新的 API 或者通过额定的代码,来正确处理辅助立体的字符。

在编程语言中应用 Unicode

次要波及以下操作:

@startuml

hide empty description

state Character
state CodePoint
state Bytes

Character -up-> CodePoint
CodePoint -down-> Character

CodePoint -down-> Bytes
Bytes -up-> CodePoint

Character -right-> Bytes
Bytes -left-> Character

@startuml

这其中最要害的就是字符和 Code Point 之间的转换。因为这里波及字符集的映射,如果编程语言不反对,咱们就要本人外挂编码表能力实现,否则无论如何都是没方法通过枚举实现的。

而有了 Code Point 当前,依据 UTF 系列编码的规定,咱们本人也能够通过代码来实现 Code Point 和字节序列的转换。当然如果编程语言内置了相干的 API,那就更不便了。

这里省略了 Code Unit 的概念,因为个别在代码中,不会有这个两头过程,间接就编码成字节序列了。

Java

char 和 String 中能够应用 \uXXXX 来示意一个 Unicode 字符。String 中能够应用两个 \uXXXX 示意一个辅助立体的字符,但 char 中不行,因为一个辅助立体字符须要用两个 char 存储:

char c = '\u4E2D';
String s = "\uD840\uDC21";

String to Code Point count:

int count = "𠀡".codePointCount(0, "𠀡".length());

String/char to CodePoint:

int i1 = Character.codePointAt(new char[] {0xD840, 0xDC21}, 0);
int i2 = "𠀡".codePointAt(0);

Code Point to String/char:

String s = new String(new int[] {0x20021}, 0, 1);
char[] c = Character.toChars(0x20021);

String to byte array:

byte[] bytes = "𠀡".getBytes(StandardCharsets.UTF_8);

Byte array to String:

String s = new String(new byte[] {(byte) 0xF0, (byte) 0xA0, (byte) 0x80, (byte) 0xA1}, StandardCharsets.UTF_8);

Normalize:

String s = Normalizer.normalize("ñ", Normalizer.Form.NFD);

JavaScript

String 中能够应用 \uXXXX 来示意一个 Unicode 字符。对于辅助立体的字符,能够应用 \u{XXXXXX} 来示意:

'\u{20021}'

String to Code Point count:

Array.from('𠀡').length

String to Code Point:

'𠀡'.codePointAt(0).toString(16)

Code Point to String:

String.fromCodePoint(0x20021)

String to byte array:

new TextEncoder().encode('𠀡')

只反对 UTF-8,其余编码方式须要本人写代码依据 Code Point 转换。


Byte array to String:

new TextDecoder('utf-8').decode(new Uint8Array([0xF0, 0xA0, 0x80, 0xA1]))

Normalize:

'ñ'.normalize('NFD')

相干文章:

  • 详解字符编码与 Unicode
  • Unicode 标准化

正文完
 0