javascript - Javascript 中如何判断字符串是否包含多字节字符?

标签 javascript string internationalization multibyte

Javascript 是否可以检测字符串是否包含多字节字符?如果有的话,能说出是哪些吗?

我遇到的问题是这样的(如果 Unicode 字符没有正确显示,我深表歉意)

s = "𝌆";

alert(s.length);    // '2'
alert(s.charAt(0)); // '��'
alert(s.charAt(1)); // '��'
<小时/>

在这里进行编辑以保持清晰(我希望) 据我现在的理解,Javascript 中的所有字符串都表示为系列 UTF-16 代码点,这意味着常规字符实际上占用 2 个字节(16 位),因此我在标题中使用“多字节”有点不对。有些字符不属于基本多语言平面 (BMP),例如上例中的字符串,因此它们占用两个代码点(32 位)。这就是我问的问题。我也不会编辑原始标题,因为对于那些不太了解这些东西的人(因此会搜索有关它的信息),“多字节”是有意义的。

最佳答案

JavaScript 字符串采用 UCS-2 编码,但可以表示基本多语言 Pane 之外的 Unicode 代码点(U+0000 - U+D7FFU+E000 - U+FFFF)使用两个 16 位数字(UTF-16代理对),其中第一个必须位于 U 范围内+D800 - U+DFFF

基于此,很容易检测字符串是否包含任何位于基本多语言平面之外的字符(这就是我认为您要问的问题:您希望能够识别字符串是否包含任何位于基本多语言平面之外的字符)在 JavaScript 表示为单个字符的代码点范围之外):

function containsSurrogatePair(str) {
    return /[\uD800-\uDFFF]/.test(str);
}

alert( containsSurrogatePair("foo") ); // false
alert( containsSurrogatePair("f𝌆") ); // true

准确计算出字符串中包含哪些代码点有点困难,并且需要 UTF-16 解码器。以下代码将字符串转换为 Unicode 代码点数组:

var getStringCodePoints = (function() {
    function surrogatePairToCodePoint(charCode1, charCode2) {
        return ((charCode1 & 0x3FF) << 10) + (charCode2 & 0x3FF) + 0x10000;
    }

    // Read string in character by character and create an array of code points
    return function(str) {
        var codePoints = [], i = 0, charCode;
        while (i < str.length) {
            charCode = str.charCodeAt(i);
            if ((charCode & 0xF800) == 0xD800) {
                codePoints.push(surrogatePairToCodePoint(charCode, str.charCodeAt(++i)));
            } else {
                codePoints.push(charCode);
            }
            ++i;
        }
        return codePoints;
    }
})();

alert( getStringCodePoints("f𝌆").join(",") ); // 102,119558

关于javascript - Javascript 中如何判断字符串是否包含多字节字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4877326/

相关文章:

javascript - 使用进度条将图像加载到 Canvas 中

javascript - 表单验证码不起作用

javascript - 如何将复选框设置为带有确认消息的按钮?

Python 3 - 用下一个字母检查字符串中的字母

python根据部分字符串匹配合并两个pandas数据框

c - C 中指针前进并在 strchr 之后再获取 2 个字符

reactjs - 使用 useTranslation() 中的 t() 时 react i18next "hooks"错误

javascript - 不同的拆分正则表达式导致 IE

symfony - 在 bundle 之间管理/共享通用翻译字符串的最佳方式

ios - 显示 HealthKit 类型的名称