标签: unicode

  • JavaScript 中使用正则 `u` 标记匹配多语言

    JavaScript 中使用正则 `u` 标记匹配多语言

    JavaScript 里使用 Unicode 编码字符串。Unicode 是一种可变长度的编码类型,大部分时候,它用两个字节表示一个字符,大部分常见字符都在这 65536 的范围内。一些少见字符,比如各种语言文字、emoji,则会用到 4 个字节。

    以前我们用正则校验字符串的时候,可以用 /[a-zA-Z0-9]/ 检查字符,这样对英文和数字没问题,但不能匹配中文。如果要匹配中文和中文标点,可以用:

    /[\u4E00-\u9FCC\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]+/g

    ES2018 之后,我们可以使用 Unicode 属性 \p{...} 来匹配某一个类型的字符串,配合 /u 标记,就可以方便地匹配多字节字符串了。

    在匹配多语言文字时,可以传入 Script 参数,达到非常高效且简便的写法。比如中文,就是 \p{sc=Han},上面那么长的穷举(其实还没举完)正则只需要这么几个简单的字符就能替换,简单多了,对吧?借用下别人的例子:

    let regexp = /\p{sc=Han}/gu; // returns Chinese hieroglyphs
    
    let str = `Hello Привет 你好 123_456`;
    
    alert( str.match(regexp) ); // 你,好

    我们还可以用这个属性来匹配俄文:\p{sc=Cyrillic}。不过有趣的是,欧洲诸国文字多少有些区别,除了我们最熟悉的英文 26 个字母,德文就有 üöä,法文也有 ù,但它们都是拉丁文, \p{sc=Latin},甚至土耳其文也是,只有俄文不一样。

    Babel 也包含了对应的插件:@babel/plugin-proposal-unicode-property-regex · Babel (babeljs.io),在古早浏览器里可以转换成非 Unicode 形态,所以基本上可以放心使用。

    还是要不断更新自己的知识才行呀。

    (更多…)
  • 零宽空格的问题与使用

    零宽空格的问题与使用

    今天有同学在群里提问:

    “我的请求路径是这样的”
    “路径上面自动多加东西了,好奇怪”

    我的第一反应是“零宽空格”,然后该同学试着手动敲了一遍 url 地址,问题果然解决了。看起来,就是因为原来的 URL 里含有零宽空格,直接复制过来,虽然看起来没问题,但是在发起请求时,非标准字符被 encode 之后就出错了。

    我们姑且不管为啥他的复制来源里会有零宽空格,聊一聊什么是“零宽空格”,以及“零宽空格”能干什么。

    零宽空格定义

    零宽空格是空格的一种空格,但是它的宽度为零,即不显示,所以看起来跟没有一样。我们可以在浏览器里启动开发者工具,然后切换到 Console 面板,输入以下代码:

    > a = '\u200b'; // 即零宽空格
    "" // 其实是有内容的,只是看不到
    > a.length
    1 // 长度为 1,说明有东西
    > encodeURIComponent(a)
    "%E2%80%8B" // encode 之后跟截图里一样,破案了

    维基百科的解释:

    零宽空格(zero-width space, ZWSP)是一种不可打印的Unicode字符,用于可能需要换行处。

    它的用法:

    在HTML页面中,零宽空格可以替代 <wbr>。但是在一些网页浏览器(例如 Internet Explorer的版本6或以下)不支持零宽空格的功能。

    MDN 上没有零宽空格的定义,但是有 <wbr> 的内容。之前我也写过一篇文章:使用 <wbr> 解决长 URL 的换行问题,里面介绍了 HTML 换行算法,以及我选择 <wbr> 的思路,建议大家看一下。

    用途一:在特定位置换行

    比如一首古诗:

    锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。

    我们有时候会希望:

    1. 在宽度足够的时候,放一行
    2. 如果宽度不够,就在标点符号处换行

    这个时候,我们可以先设置这段文字 word-break: keep-all,避免在汉字后断句换行;然后在每个标点后面加上零宽空格,这样,一行的时候就不会看到奇怪的空格,而宽度不够的时候,又能根据 white-space 属性正常换行。

    用途二:特殊标记

    我厂有一个产品,要输出大量日志,包含大量数字。为方便阅读,需要给数字添加千位分隔符;为了方便复制,又希望剪贴板上的是纯数字,不要千位分隔符;但是如果本来就是千位分隔符的,比如在别的软件里格式化的数字,就原样复制,不需要去掉千位分隔符。

    这个时候就可以用到零宽空格。我先找出来足够长的数字,然后添加千位分隔符,然后在两头加上零宽空格。这样在用户眼里,看到的是千位分隔过的数字;等他们复制的时候,我就检查两端的零宽空格,如果有的话,就复原数字;如果没有的话,就原样返回。

    其它零宽字符

    除了零宽空格之外,还有很多零宽字符,可以用来在页面中加入特殊标记,或者实现一些控制功能。大家如果发现 url encode 之后的内容和之前肉眼看到的不符,那么多半是存在零宽字符,可以试着干掉它们,多半问题就能解决。