当表情符号有肤色时,Javascript 会迭代 Unicode

Hen*_*rik 3 javascript

我现在面临的问题是,当表情符号的肤色与黄色不同时,Javascript 会将其分割为不同的字符,而不是一个字符。

\n

当我有这样的表情符号时,就没有问题了,我得到了我想要的结果。

\n

\r\n
\r\n
let strs = [...""]\n\nconsole.log(strs)\nconsole.log(strs.length)
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

但如果我有这样的表情符号,就会出现问题,因为 javascript 不允许我对这个表情符号使用 [...] 运算符:

\n

\r\n
\r\n
let strs = [...""]\n\nconsole.log(strs)\nconsole.log(strs.length)
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

我如何告诉 Javascript 这些只是一个长度为 1 的表情符号,而不是像本示例中那样的两个或多个表情符号:

\n

\r\n
\r\n
let strs = [..."\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xe2\x80\x8d"]\n\nconsole.log(strs)\nconsole.log(strs.length)
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

Nic*_*ons 6

字符串迭代器(通过扩展语法调用...)迭代字符串的代码点。有些表情符号由多个代码点组成,这会导致它们无意中分裂,如您所见。在最新版本的 lodash 中,您可以使用_.split()它来处理表情符号和 ZWJ 字符:

\n

\r\n
\r\n
const r1 = _.split("\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xe2\x80\x8d", \'\');\nconst r2 = _.split("", \'\');\n\n// See browser console for output: \nconsole.log(r1, r1.length);\nconsole.log(r2, r2.length);
Run Code Online (Sandbox Code Playgroud)\r\n
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

请注意,您不需要包含整个 lodash 库来使用此方法,相反,您可以专门包含该方法。

\n
\n

还有一个第 4 阶段的提案Intl.Segmenter,它是一个 API,允许您通过指定粒度来分割/分段字符串。它涉及创建一个分段器,可以根据其字素(即:视觉表情符号字符)分割字符串。当您在字符串上使用分段器时,您将获得一个迭代器,然后您可以使用以下命令将其转换为字符数组Array.from()

\n

\r\n
\r\n
const graphemeSplit = str => {\n  const segmenter = new Intl.Segmenter("en", {granularity: \'grapheme\'});\n  const segitr = segmenter.segment(str);\n  return Array.from(segitr, ({segment}) => segment);\n}\n// See browser console for output\nconsole.log(graphemeSplit("\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xe2\x80\x8d")); // ["\xe2\x80\x8d\xe2\x9d\xa4\xef\xb8\x8f\xe2\x80\x8d\xe2\x80\x8d"]\nconsole.log(graphemeSplit("")); // ["", "", "", "", ""]
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

  • 真是一团乱,谢天谢地,lodash! (2认同)