奇怪的重音长度为“é”字符串返回2

10

我有一个奇怪的问题无法解释。我试图处理一个带重音符号的字符串,比如 "é"。这个字符串来自于一个输入文件类型中的图片名称。

我不理解的是,为什么当我试图遍历这个字符串时,其中的重音字符会被分成两个字符。以下是一个例子,以更好地理解:

我的字符 é 被分成了两个字符,如下所示:e & ́

"é".length
=> 2

可能涉及到utf8编码?

我真的什么都不懂!


6
你使用的是哪个浏览器?在我的Chrome中返回1。 - MD Sayem Ahmed
在某些罕见的情况下,可以用两个字符来编写这封信。我是在LaTeX的上下文中读到的。 - rekire
2
你的字符在Firefox上也返回1。 - Kevin Ji
2个回答

12
他们被称为组合变音符号。它们是Unicode的一部分......可以在任何字符上“链接”的一些可组合变音符号。显然,在这种情况下,字符串的长度为2(因为有e')。像àéèìòù这样的预组合字符已被保留以实现兼容性,但现在任何字符都可以加重音符:-) 显然,99%的程序员不知道它,而99.9%的程序对其支持非常差。我相当确定它们可以在某个地方用作攻击向量(但我不是偏执狂 :-))

我甚至要补充说,即使是Skeet在2009年也不确定它们是如何工作的:http://codeblog.jonskeet.uk/2009/11/02/omg-ponies-aka-humanity-epic-fail/

你看,我记不清组合字符是在基本字符之前还是之后

:-) :-)


谢谢你的解释,但是为什么我在Chrome控制台中得到了1? - MD Sayem Ahmed
2
@SayemAhmed 因为在某个步骤中,您可能已经强制重新组合了 e + ' in a è :-) 请尝试使用 "e\u0301"; (new line) "e\u0301".length - xanatos
@xanator:明白了,谢谢。我之前只是从问题中复制了"é".length部分并将其粘贴到我的控制台上。 - MD Sayem Ahmed
1
@SayemAhmed:帖子中的OP的“é”实际上只是组合字母。 - kennytm
请注意,您可以将多个变音符号放置在单个字符的顶部,例如ẫ。 - xanatos

9

与UTF-8不同,更可能涉及组合变音符号。

>>> "e\u0301"
"é"
>>> "e\u0301".length
2

Javascript字符串通常编码为UTF-16,因此它可以在一个代码单元中包含整个字符“é”(U+00e9)。


但超出BMP范围的字符(那些代码点超过U+FFFF的字符)将返回2,因为它们被编码成2个UTF-16代码单元。

>>> "".length
2

1
关于此,请参见wikipedia - rekire
为了让问题提问者更加清楚,第二部分(关于BMP的部分)与组合变音符号是正交的。它们是不同的独立事物。Unicode的每个代码点都可以用一个JavaScript字符或两个JavaScript字符来表示。在此基础上,您可以"挂载"组合变音符号(0...n,其中n相当大),以便渲染的字形可以由1-x个JavaScript字符组成,其中x>10 :-) 啊啊...我想要表达得清楚,结果变成了5行! :-( - xanatos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接