在国际化开发中,处理字符串是不可避免的问题。不同的语言字符集不一样,有些字符还要考虑到语言语法的变化,这就需要我们在处理字符串时进行转换或者规范化。在 ES8 中新增了 String.prototype.normalize()
方法,可以用来处理不同语言字符集下的字符串规范化问题。
String.prototype.normalize() 方法介绍
String.prototype.normalize()
方法用于将语言相关的字符转换为规范化的 Unicode 字符串。该方法接受一个 form
参数,用于指定所需的规范化形式。目前规范化形式有 4 种,分别为:
NFC
:按照标准等价性合成字符串,通常用于表示语言文本;NFD
:按照标准等价性分解字符串,通常用于搜索给定文本;NFKC
:按照兼容等价性合成字符串,通常用于比较文本;NFKD
:按照兼容等价性分解字符串,通常用于处理规范化输入。
以上规范化形式解析:
- 标准等价性(Normalization Form C,NFC):是指将字符串中的 <u>组合字符</u> 转化为 <u>等价的组合字符</u> 或者 <u>标准的合成字符</u>,以达到字符规范化和统一的目的。(组合字符:一个或多个字符组合成的字符)
- 兼容等价性(Normalization Form K,NFK):在标准等价性基础上,做了更进一步的映射(Mapping),比如把平时使用中相似但 ASCII 码不同的字符映射到同一个字符,如 Full-width ASCII 转化为半角 ASCII。主要应用在 SEARCH 等场合。(Full-width ASCII:由于一些历史原因,很多 ASCII 字符都在 Unicode 中有对应的全角字符形式,所以被成为全角 ASCII。)
需要注意的是,normalize()
方法对于不支持 Unicode 的旧版浏览器将会出现异常,因此在使用时需要注意浏览器的支持情况。
代码示例
下面是使用 String.prototype.normalize()
方法将字符串规范化的代码示例:
const str = '\u1E9BE'; // 'ẞ' console.log(str.normalize('NFC')); //"ẞ" console.log(str.normalize('NFD')); //"S\u0307\u0323" console.log(str.normalize('NFKC')); //"SS" console.log(str.normalize('NFKD')); //"S\u0331S\u0307"
在上述代码中,我们将字母 ẞ
赋值给 str
变量,并利用 String.prototype.normalize()
方法将这个字符串规范化为不同形式的 Unicode 字符串。根据规范化参数的不同,规范化后的结果也不一样。
使用 String.prototype.normalize() 方法的实际应用
在实际开发中,我们经常面对国际化字符串的处理场景。下面我们分别从 <u>多语言日期格式化</u>、<u>多语言长度转换</u> 以及 <u>多语言无障碍访问文本处理</u> 三个方面进行介绍和应用。
场景一:多语言日期格式化
在不同的语言环境下,日期格式可能不同,而一些语言还存在阿拉伯语数字和西方数字的差异,比如日语数字和阿拉伯数字的表现形式就不一样:日语数字是由汉字或假名组成的,而阿拉伯数字则是1~9的阿拉伯数字。针对这种字符集不同的情况,可以使用 String.prototype.normalize()
方法将日期字符串规范化为 Unicode 字符串,以保证在不同环境下有统一的输出格式。
示例代码如下:
const date = new Date(); const options = {year: 'numeric', month: 'long', day: 'numeric'}; const formattedDate = date.toLocaleDateString('ja-JP', options); console.log(formattedDate.normalize('NFC')); //"2022年3月6日"
在上述代码中,我们使用 toLocaleDateString()
方法将当前日期转换为一个带格式的日期字符串。然后利用 String.prototype.normalize()
方法将这个字符串规范化为 Unicode 风格,以确保输出格式的一致性。接下来我们来看第二个场景。
场景二:多语言长度转换
在一些国际化应用中,需要对文本长度进行限制,以便在不同语言环境下表现一致。但是,由于一些语言特殊字符的存在,导致同样的文本在不同语言环境下字符串长度也不一样。针对这种情况,可以使用 String.prototype.normalize()
方法将字符串规范化为 Unicode 字符串,从而达到在不同语言环境下文本长度的统一。
示例代码如下:
const str = '안녕하세요!'; // 韩语你好 console.log(str.length); //7 console.log(str.normalize('NFC').length); // 5
在上述代码中,由于韩语中存在表意字符,导致同样的文本在字符长度上比较短。为了确保不同语言环境下字符长度的一致性,我们可以使用 String.prototype.normalize()
方法将字符串规范化为 Unicode 字符串,并重新计算字符串长度。接下来我们再来看第三个场景。
场景三:多语言无障碍访问文本处理
在无障碍访问的设计中,需要对一些特殊字符进行特殊处理,例如使用 aria-label 属性将一个 <button>
元素关联到它的 相关标注文本。但是,由于语言环境的不同,相关标注文本中可能会存在一些特殊字符,如单/双引号、诸如“&”和“<”等 HTML 保留字符。针对这种情况,可以使用 String.prototype.normalize()
方法将这些特殊字符规范化,以确保正确的访问性。
示例代码如下:
const text = 'Here\'s the "info " & "Help" buttons'; console.log(text.normalize('NFKC'));
在上述代码中,我们将 text
变量定义为一个包含特殊字符的字符串,并使用 String.prototype.normalize()
方法将其规范化为 Unicode 字符串,以保证特殊字符在无障碍访问时能正确展示。
总结
String.prototype.normalize()
方法是一个用于处理不同语言字符集下字符串规范化问题的实用工具函数。它使得在处理国际化字符串时不再需要考虑字符集不同或者语言语法不同的问题,同时也带来了更好的无障碍访问性。在实际的开发中,我们可以灵活地应用 String.prototype.normalize()
方法,在不同场合下实现字符串的规范化处理。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649a34cc48841e989470edc5