前言
在跨语言、跨平台开发过程中,文本的处理是一个很常见的问题。但是,不同语言对于文本的处理方式可能有所不同,特别是对于多语言的场景,文本中的字符可能会有多种编码,如何在各种编码的字符中正确地进行处理呢?
这时候我们就需要一个好用的工具来帮助我们进行文本处理。在 Node.js 版本8及以上中,提供了一个名为 @ov/grapheme-breaker 的 npm 包,它使用 Unicode Standard Annex #29 对字符串进行断字处理。在本文中,我们将介绍如何使用这个 npm 包。
安装
使用 npm 安装 @ov/grapheme-breaker,命令如下:
npm install @ov/grapheme-breaker
使用
在代码中引入 @ov/grapheme-breaker,示例代码如下:
const GraphemeBreaker = require('@ov/grapheme-breaker')
@ov/grapheme-breaker 提供了一个名为 breakIntoGraphemes 的方法,该方法将一个字符串分解为字符数组。示例代码如下:
const str = "日本语abc" const graphemes = GraphemeBreaker.breakIntoGraphemes(str) console.log(graphemes) // output: [ '日', '本', '语', 'a', 'b', 'c' ]
@ov/grapheme-breaker 还提供了一个名为 countGraphemes 的方法,该方法返回一个字符串中的字符数量。 示例代码如下:
const str = "日本语abc" const count = GraphemeBreaker.countGraphemes(str) console.log(count) // output: 6
深入理解
@ov/grapheme-breaker 使用 Unicode Standard Annex #29 对字符串进行断字处理。在了解它具体实现之前,我们先来了解一下 Unicode Standard Annex #29 中的基本概念。
基本概念
Grapheme Cluster
Unicode Standard Annex #29 中定义 Grapheme Cluster 为:一个或多个 Unicode 代码点(Code Point),其表示一个单一的认知单位。Grapheme Cluster 通常由基本的字符和组合符号或零宽空格组成。其表示的单一的认知单位,可以是一个字符或一组字符。
(Unicode 中,一个字符可以由多个 Unicode 代码点表示,而一个 Grapheme Cluster 表示一个单一的认知单位,是基于人类对于文字的认知而得出的概念,不同于系统内部的字符编码。)
Break
Unicode Standard Annex #29 中定义 Break 为:Grapheme Cluster 与其相邻的 Grapheme Cluster 之间的断开点(Boundary)。Break 分为两种类型,分别为子界(Boundary)和协定界(Limit)。子界指向的是必要的断点,而协定界则是为了解决歧义而增加的断点。
Grapheme Break Property
Unicode Standard Annex #29 中定义 Grapheme Break Property 为:一个 Unicode 代码点的属性,用于表示一个 Unicode 代码点是否为 Grapheme Cluster 的断点。具体包括以下几个属性:
- CR(见下);
- LF(见下);
- Control(控制字符): GC=Cc;
- Extend(扩展字符): GC=Cc或GC=Me或GC=Mn或GC=Mc或GC=Nd或GC=Pc;
- Prepend(前置字符): GC=Me或GC=Mn或GC=Mc或GC=Zw或GC=Ps或GC=Pf或GC=Pi或GC=Pc或u或GC=B;
- SpacingMark(空格记号): GC=Mcc或GC=Mn或GC=Mc;
- L(字母): GC=L;
- V(韵母): GC=L;
- T(音调): GC=Mn或GC=Me;
- LV(字母性韵母): GC=L;
- LVT(字母性韵母前韵母+音调): GC=L;
- Other(其他符号): GC=Cf、GC=Co、GC=Cs、GC=No、GC=So、GC=Lo、GC=P。
其中,CR和LF指的是“回车”(\r)和“换行”(\n)字符,他们不是断点,而是协定界,后文中称为“换行符”。除此之外,其他的属性中,GC=Cc、GC=Co、GC=Cs、GC=No、GC=So、GC=Lo、GC=P 都属于“子界”,其他属性均属于“协定界”。
@ov/grapheme-breaker 的实现
@ov/grapheme-breaker 的主要实现思路是:从头到尾依次扫描字符串中的每个字符,如果当前字符为断点,则将其记录下来。扫描到字符串的最后一个字符,同时计算出断点位置后,即可得到字符串中所有 Grapheme Cluster。
@ov/grapheme-breaker 中的字符分类方式,与 Unicode Standard Annex #29 中的 Grapheme Break Property 概念相对应。它将每个字符都分为以下8类:
- Prepend:所有属于协定界 Prepend 的字符;
- CR:回车符,属于协定界;
- LF:换行符,属于协定界;
- Control:控制字符,属于子界;
- Extend:扩展字符,属于子界;
- SpacingMark:空格记号,属于子界;
- L:字母性字符,属于子界;
- Other:其他符号,属于子界。
从第一个字符开始扫描,如果当前字符是 Prepend 类型,则将其记录下来,并从下一个字符开始继续扫描;如果当前字符为 LF 或 CR 类型,则将其记录下来,然后从下一个字符开始扫描;如果当前字符为其他类型,则从当前字符开始寻找下一个断点,作为当前 Grapheme Cluster 的结尾。
指导意义
@ov/grapheme-breaker 是一个用于 Unicode 中文本断字处理的好工具,常常被用于实现多语言界面的显示和输入,以及搜索引擎的分词等应用场景。通过学习和使用 @ov/grapheme-breaker,我们可以更深入地了解 Unicode 中的文本处理原理和相关概念,为我们的前端开发工作带来更广阔的思路和更高的效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60055b0c81e8991b448d8b37