【问题标题】:What is a surrogate pair?什么是代理对?
【发布时间】:2015-11-06 07:48:59
【问题描述】:

我在一个 javascript 开源项目中遇到了这段代码。

validator.isLength = function (str, min, max) 
    // match surrogate pairs in string or declare an empty array if none found in string
    var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
    // subtract the surrogate pairs string length from main string length
    var len = str.length - surrogatePairs.length;
    // now compare string length with min and max ... also make sure max is defined(in other words, max param is optional for function)
    return len >= min && (typeof max === 'undefined' || len <= max);
};

据我了解,上面的代码正在检查字符串的长度,但没有考虑代理对。所以:

  1. 我对代码的理解正确吗?

  2. 什么是代理对?

到目前为止,我只发现这与编码有关。

【问题讨论】:

标签: javascript string encoding utf string-length


【解决方案1】:
  1. 是的。你的理解是正确的。该函数以 Unicode 代码点返回字符串的长度。

  2. JavaScript 使用 UTF-16 对其字符串进行编码。这意味着两个字节(16 位)用于表示一个 Unicode 代码点。

    现在 Unicode 中的字符(如表情符号)具有如此高的代码点,因此它们无法存储在 2 个字节(16 位)中,因此需要将它们编码为两个 UTF-16 字符(4 个字节)。这些被称为代理对。

试试这个

var len = "?".length // There is an emoji in the string (if you don’t see it)

var str = "?"
var surrogatePairs = str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || [];
var len = str.length - surrogatePairs.length;

在第一个示例中,len 将为 2,因为 Emoji 由两个 2 UTF-16 字符组成。在第二个示例中,len 将为 1。

您可能想阅读 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) by Joel Spolsky

【讨论】:

    【解决方案2】:

    你试过用谷歌搜索吗?

    最好的描述是http://unicodebook.readthedocs.io/unicode_encodings.html#surrogates

    在 UTF-16 中,一些字符以 8 位存储,而另一些则以 16 位存储。

    代理对是一个 16 位的字符表示。 某些字符代码被保留为此类对中的第一个。

    【讨论】:

    • 重新阅读您的链接参考。 “在 UTF-16 中,U+0000-U+D7FF 和 U+E000-U+FFFD 范围内的字符存储为单个 16 位单元。非 BMP 字符(范围 U+10000-U+10FFFF)存储为“代理对”,两个 16 位单元……”因此,UTF-16 中的字符将是 16 位,或者,如果需要代理对,则为 32 位。没有字符存储为 8 位。
    • 我赞成这个答案,因为这个参考给出了代理对如何在 UTF-16 中工作的最佳描述。简而言之,U+0000-U+D7FF和U+E000-U+FFFD被编码为2个字节;超过 U+10000 的任何内容都被编码为从该范围 U+D800-U+DFFF 的间隙中抽取的两个字符的“代理对”。一个单独的代理字符无效,这就是stackoverflow.com/a/31986749/1799811 中的上述正则表达式有效的原​​因(为简洁起见,我省略了少量的复杂性)
    【解决方案3】:

    关于你的第二个问题: 1.What is a "surrogate pair" in Java? 术语“代理对”是指在 UTF-16 编码方案中对具有高代码点的 Unicode 字符进行编码的一种方法。

    在 Unicode 字符编码中,字符被映射到 0x0 到 0x10FFFF 之间的值。

    在内部,Java 使用 UTF-16 编码方案来存储 Unicode 文本字符串。在 UTF-16 中,使用 16 位(两字节)代码单元。由于 16 位只能包含从 0x0 到 0xFFFF 的字符范围,因此会使用一些额外的复杂性来存储高于此范围(0x10000 到 0x10FFFF)的值。这是使用称为代理的代码单元对完成的。

    代理代码单元位于称为“低代理”和“高代理”的两个范围内,具体取决于它们是否允许在两个代码单元序列的开头或结尾。

    1. https://msdn.microsoft.com/en-us/library/windows/desktop/dd374069%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

    希望这会有所帮助。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • 接受并更改。
    猜你喜欢
    • 2011-08-19
    • 2018-02-03
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 2011-11-14
    • 1970-01-01
    • 2011-09-11
    相关资源
    最近更新 更多