如何使用带有特殊 unicode 字符的子字符串?

Val*_*uiz 5 javascript unicode substring utf-8 substr

var string = "abc";
var lastchar = string.substr(string.length - 1);
console.log(lastchar);
Run Code Online (Sandbox Code Playgroud)

这返回?代替

T.J*_*der 6

在 JavaScript 中,字符串是一系列 UTF-16 代码单元(详细信息请参阅我的博客文章什么是字符串?)。在 UTF-16 中,最后一个字形(宽松地称为“字符”)需要两个代码单元(它们组合起来形成一个代码),因此字符串长度为 5。

\n

在 ES2015 之前,JavaScript 中并没有太多内置功能来帮助您解决此问题,但是当引入可迭代性时,字符串变得可迭代,并且它们迭代其代码点,而不是代码单元。展开操作使用迭代,因此您可以将该字符串展开到数组中以获取其代码点:

\n

\r\n
\r\n
const string = "abc";\nconsole.log(string.length); // 5\nconst chars = [...string];\nconsole.log(chars.length);  // 4\nconst lastchar = chars.slice(chars.length - 1).join("");\nconsole.log(lastchar);
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

这只是一个示例,用于演示区别以及如何相当轻松地使用代码点。

\n

即使代码点也不一定是字形,因为某些代码点与其他代码点组合形成单个字形。(例如,在梵文中,该语言的单词是“\xe0\xa4\xa6\xe0\xa5\x87\xe0\xa4\xb5\xe0\xa4\xa8\xe0\xa4\xbe\xe0\xa4\x97 \xe0\xa4\xb0\xe0\xa5\x80" 对于本机读者来说看起来像是五个字形,但实际上是八个代码点,因为其中一些是用后面经过元音代码点修改的基本音节字形编写的。)正在开发的新产品Intl.Segmenter也将有助于解决这些情况。

\n