过滤XML退格控制字符(\b或BS)

作者:杨润炜
日期:2016/1/12 17:19

问题描述

今天搞网站的rss源时遇到一个问题,xml解析报错,信息如下:
xml-error
“Input is not proper UTF-8, indicate encoding!”是在说xml中有字符无法用utf8规则解析。

查看页面源代码,全选复制粘贴到sublime后发现了如下”BS”的特殊字符,如图:
BS

粘贴到chrome控制台来处理一下,得到如下结果:
console

这就说明这个特殊字符是不可显示的,但可以知道它的16进制是:08。

ASCII码控制字符对照表,如图:
ASCII

在阮一峰的这篇文章中了解到utf8、ASCII、unicode的一些区别。

原先还怀疑是unicode中没有对ASCII的控制字符作声明,所以才使得utf8无法对此作解析。但无论是在维基百科上的unicode字符列表utf8上都看到有对十六进制范围为0000到007f的编码声明,还是js可以对这一控制字符进行十六进制的转换,这些都表明utf8是可以对所以ASCII作解析的(实际上它只用一个字节就对所有128个ASCII字符作编码)。

所以我换了个思路来思考这个问题,会不会是xml不让输入这些控制字符呢?
google了下,果然发现了这篇文章,而且恰好能说明这个问题。
实际是,所有ascii控制字符在xml都不给解析,然而之前那个报错信息把我的思路引到了另一个问题上去了。

解决问题

因为这个特殊字符在正常情况下无法显示,所以无法用常规的方法替换掉。但我们可以利用它的十六进制来做文章。先将可能含有特定字符的文本用encodeURIComponent转换成十六进制表示,然后repalce掉%08字符,再decodeURIComponent。具体代码是:

  1. function filterBS(str) {
  2. if (!str) {
  3. return str;
  4. }
  5. return decodeURIComponent(encodeURIComponent(str).replace(/%08/g, ''));
  6. }

这里只是替换掉了退格这个控制字符,具体可以控制上述acsii表中的十六进制数进行替换。

思考回顾

做完之后一直在想,如果某个字符的十六进制是%08xx或%08xxxx或%08xxxxxx,那上述解决方法将会使这个字符错误地显示甚至是乱码。但在实际反复试验中,并没有出现这种情况。是试验的字符量太少了么?
实际上,在上述问题描述中,我们已经发现了utf8对ASCII的编码只需要一个字节,即0x00到0x7F,而且utf8中如果第一个字节以二进制0开始的话,则说明这个字符只需要一个字节,所以不会出现上述的可能情况。

至于为啥内容里会有这种控制字符,这就不得而知了。可能是公司编辑们复制粘贴其它平台或者其它编辑器的内容导致的。

感谢您的阅读!
如果看完后有任何疑问,欢迎拍砖。
欢迎转载,转载请注明出处:http://www.yangrunwei.com/a/17.html
邮箱:glowrypauky@gmail.com
QQ: 892413924