zoukankan      html  css  js  c++  java
  • String.prototype.normalize()

    normalize() 方法会按照指定的一种 Unicode 正规形式将当前字符串正规化.
    这是一个ES6方法。

    许多欧洲语言有语调符号和重音符号。为了表示它们,Unicode 提供了两种方法。一种是直接提供带重音符号的字符,比如Ǒ(u01D1)。另一种是提供合成符号(combining character),即原字符与重音符号的合成,两个字符合成一个字符,比如O(u004F)和ˇ(u030C)合成Ǒ(u004Fu030C)。

    这两种表示方法,在视觉和语义上都等价,但是 JavaScript 不能识别。

    'u01D1'==='u004Fu030C' //false
    
    'u01D1'.length // 1
    'u004Fu030C'.length // 2

    ES6 提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

    'u01D1'.normalize() === 'u004Fu030C'.normalize()
    // true

    normalize方法可以接受一个参数来指定normalize的方式,参数的四个可选值如下。

    • NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
    • NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
    • NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
    • NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。
    'u004Fu030C'.normalize('NFC').length // 1
    'u004Fu030C'.normalize('NFD').length // 2

    normalize方法目前不能识别三个或三个以上字符的合成。这种情况下,还是只能使用正则表达式,通过 Unicode 编号区间判断。

    6.2 适用于Unicode的方法

     遇到像UTF-8这样的输入时,一种方法是将输入标准化(使用定义好的规则集将Unicode转换成最简单的形式)。Unicode标准化与规范化的差别在于:根据使用规则集的不同,Unicode字符可能会存在多种标准形式,可以使用NFKC(Normalization Form KC)作为输入验证的标准化形式。

     标准化操作将Unicode字符分解成有代表性的组件,之后按照最简单的形式重组该字符。大多数情况下,它会将双倍宽度及其他Unicode编码在它所在的位置转换成各自的ASCII等价形式。

     Java:

    normalized = Normalizer.normalize(input, Normalizer.Form.NFKC)

     C#:

    normalized = input.Normalize(NormalizationForm.FormKC);

     PHP:

    $normalized = I18N_UnicodeNormalizer::toNFKC($input,  'UTF-8');  // PEAR:I18N_UnicodeNormalizer

    还有一种方法是首先检查Unicode是有效的,然后将数据转换成一种可预见的格式,eg. ISO-8859-1.

    下表列出的正则可以匹配使用UTF-8编码的Unicode的有效性:

    ---------------------------------------------------------------------------
        正则表达式                  描述
    ----------------------------------------------------------------------------  

            [x00-x7F]                ASCII
            [xC2-xDF][x80-xBF]          双字节表示
            xE0[xA0-xBF][x80-xBF]          双字节表示
            [xE1-xECxEExEF][x80-xBF]{2}    三字节表示
            xED[x80-x9F][x80-xBF]          三字节表示
            xF0[x90-xBF][x80-xBF]{2}         PANEL 1 TO 3
            [xF1xF3][x80xBF]{3}            PANEL 4 TO 15
            xF4[x80-x8F][80-xBF]{2}         PANEL 16

    ----------------------------------------------------------------------------

     检查完是有效的格式后,就可以将其转换成可预见的格式,eg. UTF-8 => ISO-8859-1(Latin 1)

     Java: String ascii = utf8.getByte("ISO-8859-1");

     C# : byte[] asciiBytes = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, utf8bytes);

     PHP: ascii =  utf8_decode($utf8string);

  • 相关阅读:
    Doing Homework 简单dp&&状态压缩
    嫖裤子序列
    王宁宁宁
    友军寻路法
    Viviani
    ccf 201909-3
    ccf 201909-5
    链式前向星
    ccf-201909-04
    ccf -201909-2
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/10365701.html
Copyright © 2011-2022 走看看