转义字符

一些特殊字符。

转义字符 含义
\n 换行
\r 回车
\0 结束字符
\s 空格
\’ 单引号
\" 双引号
\\ 反斜杠

字符编码

ASCII

American Standard Code for Information Interchange,美国信息交换标准代码。

计算机发明之初,基本只考虑了美国的需求,美国大概只需要 128 个字符。

数字 32~126 表示的字符都是可打印字符。

Java 字符编码

0~31 和 127 表示一些不可打印的字符。

数字 缩写/字符 解释 转义字符
0 NUL(null) 空字符 \0
8 BS(backspace) 退格 \b
9 HT(horizontal tab) 水平制表符 \t
10 LF(NL line feed,new line) 换行键 \n
13 CR(carriage return) 回车键 \r
27 ESC 换码
127 DEL(delete) 删除

ASCII 码对美国够用,但对其他国家是不够的。

各国的计算机厂商发明了各自的编码方式以表示自己国家的字符,为了保持与 ASCII 码的兼容性,一般都是将最高位设置为 1。

就是说,当最高位为 0 时,表示 ASCII 码,当为 1 时就是各个国家自己的字符。

ISO 8859-1

ISO 8859-1 又称 Latin-1,同样使用一个字节表示一个字符。

其中 0~127 与 ASCII 一样,128~255 规定了不同的含义。

Windows-1252

基本上可以认为,ISO8859-1 已被 Windows-1252 取代,在很多应用程序中,即使文件声明它采用的是 ISO 8859-1 编码,解析的时候依然被当作 Windows-1252 编码。

GBK

GBK 使用固定的两个字节表示字符,高位字节范围是 0x81~0xFE ,低位字节范围是 0x40~0x7E 和 0x80~0xFE。

需要注意的是,低位字节是从 0x40(即64)开始的,因此低位字节的最高位可能为 0。

Unicode

Unicode 给世界上所有字符都分配了一个唯一的数字编号,编号范围从 0x000000~0x10FFFF。

每个字符都有一个 Unicode 编号,这个编号一般写成十六进制,在前面加 U+。

但它并没有规定这个编号怎么对应到二进制表示。

编号怎么对应到二进制表示?主要有 UTF-32、UTF-16 和 UTF-8 。

UTF-32

字符 Unicode 编号的整数二进制形式,4个字节。

UTF-16

UTF-16 使用变长字节表示。对于编号在 U+0000 ~ U+FFFF的字符(常用字符),直接用 2 个字节表示。编号在 U+10000 ~ U+10FFFF的字符(增补字符集),需要使用 4 个字节表示。

在 Java 内部进行字符处理时,采用的是 Unicode 编码,具体的编码格式是 UTF-16。

UTF-8

UTF-8 使用变长字节表示,字符使用的字节个数与其 Unicode 编号的大小有关,编号小的使用的字节就少,字节个数为 1~4 不等。

编号范围 二进制格式
0x00 ~ 0x7F(0 ~ 127) 0xxx xxxx
0x80 ~ 0x7FF(128 ~ 2047) 110x xxxx 10xx xxxx
0x800 ~ 0xFFFF(2048 ~ 65535) 1110 xxxx 10xx xxxx 10xx xxxx
0x10000 ~ 0x10FFFF(65536以上) 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

UTF-8 将字符看作整数,转化为二进制形式(去掉高位的 0),然后将二进制位从右向左依次填入对应的二进制格式 x 中,填充完后,如果对应的二进制格式还有没填的 x,则设为 0。

/*
如 '马' 的 Unicode 编号是 0x9A6C,整数编号是 39532,二进制 1001 101001 101100
对应的 UTF-8 二进制格式是:1110 xxxx 10xx xxxx 10xx xxxx
将二进制 1001 101001 101100 从右到左依次填入二进制格式中
结果就是其 UTF-8 编码:1110 1001 1010 1001 1010 1100
*/

UTF-8 是兼容 ASCII 的,对大部分中文字符而言,需要使用三个字节表示。

编码转换

不同编码格式之间可以借助 Unicode 编号进行编码转换。可以认为,每种编码都有一个映射表,存储 Unicode 编号和其特有的字符编码之间的对应关系。

编码转换的具体过程可以是:一个字符从 A 编码转到 B 编码,先找到字符的 A 编码格式,通过 A 编码的映射表找到其 Unicode 编号,然后通过 Unicode 编号再查找 B 编码的映射表,找到字符的 B 编码格式。

乱码问题

解析错误:使用错误的编码进行解析,如小明采用 Windows-1252 写了个文件,发送给了小红,小红 使用 GBK 来解析这个字符,看到的可能就是乱码。

编码转换错误:在错误解析的基础上还进行了编码转换。如上述,小红用 GBK 解析打开后看到乱码,又转换成了 UTF-8 编码。

发表回复