资讯专栏INFORMATION COLUMN

细说Unicode(三) Unicode 番外之附加字符

qujian / 1773人阅读

摘要:在各种论坛上,经常会看到一些奇怪的字符,它们的内容会超出显示范围,举个例子常见的还有一些有泰文字符组成的。第一种是对字符串文字区域设置最大高度,超出的部分自动隐藏。将附加字符进行过滤,这种方法在某种程度上会误杀一些需要正常显示的附加符号。

在各种论坛上,经常会看到一些奇怪的字符,它们的内容会超出显示范围,

举个例子:

"Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞"

常见的还有一些有泰文字符组成的。这里就不举例子了。这些看似乱文的字符是怎么形成的呢?

其实它们并不是乱文,尝试输出上面那个例子的字符长度

"Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞".length; //75

发现竟然包含了75个字符!我们用Array.from输出这些字符:

Array.from("Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞");
//["Z", "͑", "ͫ", "̓", "ͪ", "̂", "ͫ", "̽", "͏", "̴", "̙", "̤", "̞", "͉", "͚", "̯", "̞", "̠", "͍", "A", "ͫ", "͗", "̴", "͢", "̵", "̜", "̰", "͔", "L", "ͨ", "ͧ", "ͩ", "͘", "̠", "G", "̑", "͗", "̎", "̅", "͛", "́", "̴", "̻", "͈", "͍", "͔", "̹", "O", "͂", "̌", "̌", "͘", "̨", "̵", "̹", "̻", "̝", "̳", "!", "̿", "̋", "ͥ", "ͥ", "̂", "ͣ", "̐", "́", "́", "͞", "͜", "͖", "̬", "̰", "̙", "̗"]

再查看其中某个字符的Unicode码点:

Array.from("Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞")[10].codePointAt(0);//793,即16进制的0x0319

根据Unicode映射表查找出0x0319对应的字符,发现U+0300~U+036F称为结合附加符号,那么结合附加符号又是什么?

附加符号,是添加在字母上面的符号,以更改字母的发音或者以区分拼写相似词语。例如汉语拼音字母“ü”上面的两个小点,或“á”、“à”字母上面的标调符。变音符号可以放在字母的上方或下方,也可以放在其他的位置。当多个附加符号叠加的时候,就形成了看起来像乱码的符号。

而在泰文中,字符的组成也是由一些元音符号和声调符号组成的

所以多个元音符号或声调符号叠加时也会有类似的效果。这里就不再做阐述。

在网页开发中,特别是评论区,如果遇到太多的"插楼"字符,就会对其他用户造成阅读障碍,影响阅读体验,那怎么避免这种情况呢。这里提供两种方法。

第一种是对字符串文字区域设置最大高度,超出的部分自动隐藏。

p {
    height: 20px;
    overflow: hidden;
}

另一种方式就是对这种特殊字符做过滤操作。将附加字符进行过滤,这种方法在某种程度上会误杀一些需要正常显示的附加符号。但一般也不会影响整体功能,利大于弊。

var regexSymbolWithCombiningMarks = /([-u02FFu0370-u1DBFu1E00-u20CFu2100-uD7FFuDC00-uFE1FuFE30-uFFFF]|[uD800-uDBFF][uDC00-uDFFF]|[uD800-uDBFF])([u0300-u036Fu1DC0-u1DFFu20D0-u20FFuFE20-uFE2F]+)/g;

function getSymbolsIgnoringCombiningMarks(string) {
    // 删除附加符号:
    var stripped = string.replace(regexSymbolWithCombiningMarks, function($0, symbol, combiningMarks) {
        return symbol;
    });
    
    return stripped;
}

getSymbolsIgnoringCombiningMarks("Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞"); //"ZALGO!"

讲到这里,我们对Unicode已经有了比较细致的了解。相信在开发中碰到问题也能找出根源所在了。

通过学习编码的历史,原理以及查询映射表,我们知道了乱码是怎么产生的,并且利用ES6或正则表达式,来解决绝大多数编码问题。

参考文章:
https://zh.wikipedia.org/wiki
https://mathiasbynens.be/note...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86748.html

相关文章

  • 细说Unicode(二) Unicode与JavaScript的纠葛

    摘要:受到这个的影响,中的字符操作函数某些情况无法返回正确的结果。的码点,还有另外一种表示方法,称为进制转义序列。这与我们的认知有点不同,我们通常认为一个表情符号也是一个字符,长度为。而如果通过来判断字符串长度显然是不够准确的。 大家对上一篇文章中提到的UCS编码可能比较陌生。殊不知这就是JavaScript采用的编码方法。 既然Unicode已经统一了天下,为什么JavaScript不采用...

    Achilles 评论0 收藏0
  • 细说Unicode(一) Unicode初认识

    摘要:所以中国人自己创造了一种字符编码,每个汉字和符号用两个字节来表示。第一个字节称为高位字节,第二个字节称为低位字节。而目前为止我们使用最广泛的中文编码还是。 网站开发中经常会被乱码问题困扰。知道文件编码错误会导致乱码,但对其中的原理却知之甚少。偶然从某篇文章了解了Unicode,发现从这条线出发也牵引出了一系列缺失的知识点。通过研读文章,基本了解了一些以前不明白的问题,所以整理了几篇,从...

    loostudy 评论0 收藏0
  • 关于Python编码这一篇文章就够了

    摘要:每个字符都可以编码为唯一的序列。但在中还有其他的数字系统,通过其他方式是表示数字。事实上,是的完美子集。里的编码与解码的类型用于表示人类可读的文本,可以包含任何字符。编码的文本表示为二进制数据字节。 概述 在使用Python或者其他的编程语言,都会多多少少遇到编码错误,处理起来非常痛苦。在Stack Overflow和其他的编程问答网站上,UnicodeDecodeError和Unic...

    ispring 评论0 收藏0
  • 关于Python编码这一篇文章就够了

    摘要:每个字符都可以编码为唯一的序列。但在中还有其他的数字系统,通过其他方式是表示数字。事实上,是的完美子集。里的编码与解码的类型用于表示人类可读的文本,可以包含任何字符。编码的文本表示为二进制数据字节。 概述 在使用Python或者其他的编程语言,都会多多少少遇到编码错误,处理起来非常痛苦。在Stack Overflow和其他的编程问答网站上,UnicodeDecodeError和Unic...

    YorkChen 评论0 收藏0
  • PHP实现Unicode和Utf-8编码的互相转换

    摘要:假如在中汉字你的编码为,把它转换为二进制为,然后按照的方法进行转换。在将所得到的结果左移位与最高字节所得的结果取或,第二位就这样完成了,得到的结果为。 最近恰好要用到unicode编码的转换,就去查了一下php的库函数,居然没找到一个函数可以对字符串进行Unicode的编码和解码!也罢,找不到的话就自己实现一下了。。。 Unicode和Utf-8编码的区别 Unicode是...

    qianfeng 评论0 收藏0

发表评论

0条评论

qujian

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<