在html中总会出现一些以&#x开头的字符串,但是在浏览器中就会显示出正常的我们所熟知的字符,使用decode/unescape/decodeURI解码均无效,因为,这不是编码。
那么为什么会有这些字符出现呢?
#1# 那要从字符编码说起......
读写文字是人与动物的最大区别,不同的种族发明了不同的语言文字,对这些文字进行二进制表示是计算机领域必须要解决的问题。文本处理在计算机程序中占有相当大的比例,尤其是在web程序中,几乎大部分程序逻辑都是为了最终输出处理过的文本。目前世界上存在有很多种字符编码标准,各个标准并不完全兼容,甚至完全不同,从而导致了“乱码”这个让很多程序员都胆战心惊的东西。
尽管目前统一的编码规范UNICODE大行其道,被越来越广泛地使用,然而尚未达到完全统治字符编码界的水平。
#2# 再说一下元字符:
在标记语言中,都会定义一些被称为“元字符”的特殊字符,这些字符具有特殊的作用,不再具有原来字面上的意义。我们以HTML为例,小于号(<)就是一个最常用的元字符,它表示一个标签的开始,而不再具有“小于号”这个字面意义。
那么想要这些元字符的字面含义该怎么办呢?
解决方法就是:用元字符引导字符序列来表示元字符的字面含义。例如在HTML中元字符<的字面值就是用如下序列表示。
<
像“<”和“>”这类符号已经用来表示HTML标签,因此就不能直接当作文本中的符号来使用。为了在HTML文档中使用这些符号,就需要定义它的转义字符串。当解释程序遇到这类字符串时就把它解释为真实的字符。在输入转义字符串时,要严格遵守字母大小写的规则。转义字符串(Escape Sequence)也称字符实体(Character Entity)。
再比如说,HTML会自动截去多余的空格。不管你加多少空格,都被看做一个空格。比如你在两个字之间加了10个空格,HTML会截去9个空格,只保留一个。为了在网页中增加空格,你可以使用 表示空格。下表中表示就是最常用的一些字符实体。
#3# 除此以外还有一些不可编码字符......
很多的字符编码标准并不能涵盖所有的字符,例如ASCII编码只包含128个字符,根本不能表示英文之外的其他任何语言文字。这样就会导致一个问题:想要在ASCII编码的文件中记录汉字怎么办?
解决方法就是:用元字符引导的可编码字符序列来表示不可编码字符。解码程序能够识别这个格式的字符序列,然后把它转换成原本的不可编码字符。例如,汉字“中”在ASCII编码的HTML文件中可以使用如下序列表示。
中
这个序列只含有可以用ASCII编码的字符。浏览器在遇到这个序列时,自动转换为汉字“中”并正确显示出来,当然前提是浏览器自身具有显示汉字的能力。
前面提到的元字符引导的可编码字符序列到底是如何规定的呢?目前有两种方案:
1>一种就是在html中常用的被称为实体的规范
例如上面提到的
<
这种规范中定义了很多特定的字符序列,然而总归是非常有限的,主要是为了表示元字符的字面值。对于广大的汉字仍不能表示。
2>另一种就是被称为NCR的规范
在NCR中,使用字符的UNICODE代码点数值的十进制或十六进制表示字符串来代表这个字符。例如上面例子中
中
其中的20013就是汉字“中”在UNICODE编码中的代码点。当然也可以使用16进制来表示,如下
中
这种规范看似简单,却非常强大,因为它可以表示任意的字符,只用UNICODE编码中定义了这个字符,它就可以轻松表示。存在的问题是,很少有人能记住一个字符的UNICODE代码点,需要去查表才行。
尽然NCR能表示任何字符,当然也能够表示元字符的字面值了,例如前面的
<
也可以使用
<
来表示。
总的来说,形如
&name;
&#dddd;
&#xhhhh;
的一串字符是 HTML、XML 等 SGML 类语言的转义序列(escape sequence)。它们不是「编码」。以 HTML 为例,这三种转义序列都称作 character reference:第一种是 character entity reference,后接预先定义的 entity 名称,而 entity 声明了自身指代的字符。
后两种是 numeric character reference(NCR),数字取值为目标字符的 Unicode code point;以「&#」开头的后接十进制数字,以「&#x」开头的后接十六进制数字。
从 HTML 4 开始,NCR 以 Unicode 为准,与文档编码无关。「中国」二字分别是 Unicode 字符 U+4E2D 和 U+56FD,十六进制表示的 code point 数值「4E2D」和「56FD」就是十进制的「20013」和「22269」。所以
我给加了空格,不然网页会自动渲染成文字...
&#x 4e2d;&#x 56fd;
&# 20013;&# 22269;
这两种 NCR 写法都会在显示时转换为「中国」二字。NCR 可以用于转义任何 Unicode 字符,而 character entity reference 很受限,参见 HTML 4 和 HTML5 中已有定义的字符列表:
Character entity references in HTML 4
Character entity references in HTML5
#4# 你不知道的unicode
UNICODE编码涵盖了世界上已知的所有字符,除了各种语言的文字外,还包含了很多符号,标记。下面给出几个小例子。
- ★ 对应 ★
- ⚔ 对应 ⚔
- ⚕ 对应 ⚕
- ✓ 对应 ✓
另外,UNICODE中还定义了一些组合字符,它们本身不能单独存在,必须作用于前面的基本字符上,例如常见的重音符号。
- A̎ 对应 A̎
广大的90后小朋友网络上广泛使用的火星文就是把各种UNICODE字符按照特定的规则组合起来的。
如下序列:
づ火☆攵ā
显示效果:
づ火☆攵ā
但是有时候我们在解析html的时候需要对它进行反转义,所以查找了一些方法:
1>自然是自己编程实现,但是总是不是那么完整
2>借用第三方包,如果是java,可以使用apache工具包common-lang中有一个很有用的处理字符串的工具类StringEscapeUtils,里面有很多静态的方法,可以直接通过类来调用。
String str1 = StringEscapeUtils.unescapeHtml4("Log in to your PayPal Account");
System.out.println(str1);
就可以得到反转义结果:
Log in to your PayPal Account