Js如何正确遍历"⚓️中文abc𠮷"并正确取出其中的每一个字符?(for..of无法正确遍历)

网上找到判断2or4字节的方法:

function is32Bit(c) {
  return c.codePointAt(0) > 0xFFFF;
}

旧问题:

这个方法只能判断部分4字节字符,如“🍔”、“𠮷”,但是无法判断“✈️”、“⚓️”等。那么如何判断“✈️”、“⚓️”这样的字符以及“⚓️中文abc𠮷”这种字符的字符个数?(已解决,见“旧问题解决方案”

我找到的规律:

1.“✈️”、“⚓️”的码点与大部分emoji的码点不同,Unicode官方给出的码点数比较小。比如“✈️”是"U+2708",而“🍔”是U+1F354。一个小于0xFFFF,另一个大于0xFFFF。

2.ES6给出的声称可以正确识别4字节字符的方法String.codePointAt,获取的码点与Unicode官方是一致的。(for...of等也是一致的)

    "🍔".codePointAt(0).toString(16) // "1f354" 官方码:U+1F354
    "✈️".codePointAt(0).toString(16) // "2708"  官方码:U+2708

3.但在js里,"u{2708}"并不是"✈️"的对应码点,打印出来是“✈”。所以codePointAt方法没法获取这种emoji在js中的正确码点,只是获取了官方码。

"✈" === "✈️" //false
"✈".normalize() === "✈️".normalize() //false

4.我用js找出他们的正确码点(拆分形式的码点),发现他们的码点都是官方给出的码点与另一个固定值("ufe0f")的符合。:

  • "✈️"的码点:"\u2708\ufe0f" (官方码:U+2708)
  • "⚓️"的码点:"\u2693\ufe0f" (官方码:U+2693)

附:

1.我用的找出特殊码点的方法:

var strArr = [];
var str = "";

strArr.push("\\u" + "⚓️".charCodeAt(0).toString(16)) //  "\u2693"
strArr.push("\\u" + "⚓️".charCodeAt(1).toString(16)) //  "\ufe0f"

str = strArr.join("") //  "\u2693\ufe0f"

console.log(eval("'" +  str + "'")); //⚓️

2.Unicode官方网站的《Emoji-list》。(码点表)

旧问题解决方案:

如何正确返回"⚓️中文abc𠮷"这种字符串的字符个数?

一楼的大佬分享的干货中的regexSymbolWithCombiningMarks 方法可以正确返回"⚓️中文abc𠮷"的length。(目前找到最精确的办法,支持ES3。但是还是有诸如“👨‍👩‍👧‍👦”这种字符不能正确返回length,详见此文章。)

新问题:

如何正确遍历"⚓️中文abc𠮷"并正确取出其中的每一个字符?目前for..of不能正确取出"⚓️"。
(抱歉我才疏学浅,判断完长度却不知道哪一截是4字节,还是没法正确取出这些字符。貌似用正则应该有办法的,但是我不知道怎么写……)

阅读 4.3k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏