如何从JavaScript中的字符串中获取第n个(Unicode)字符

epi*_*ian 9 javascript unicode

假设我们有一个包含一些(星体)Unicode字符的字符串:

const s = 'Hi  Unicode!'
Run Code Online (Sandbox Code Playgroud)

[]运营商和.charAt()方法不为获得第四字符,这应该是""工作:

> s[3]
'?'
> s.charAt(3)
'?'
Run Code Online (Sandbox Code Playgroud)

.codePointAt() 确实获得第四届字符正确的值,但不幸的是它是一个数字,并且必须转换回使用字符串String.fromCodePoint():

> String.fromCodePoint(s.codePointAt(3))
''
Run Code Online (Sandbox Code Playgroud)

类似地,使用splats将字符串转换为数组会产生有效的Unicode字符,因此这是获得第4个字符的另一种方法:

> [...s][3]
''
Run Code Online (Sandbox Code Playgroud)

但我无法相信从字符串到数字返回字符串,或者必须将字符串拆分为数组是执行这个看似微不足道的事情的唯一方法.这样做有没有简单的方法?

> s.simpleMethod(3)
''
Run Code Online (Sandbox Code Playgroud)

注意:我知道"字符"的定义有点模糊,但出于这个问题的目的,字符只是与Unicode代码点相对应的符号(没有组合字符,没有字形集群等).

更新:该String.fromCodePoint(str.codePointAt(n))方法不可行,因为n那里的位置没有考虑以前的星体符号:String.fromCodePoint(''.codePointAt(1)) // => '?'


(我觉得有点愚蠢地问这个;就像我可能错过了一些明显的东西.但是这些问题的先前答案不适用于在星体平面上使用Unicode simbols的字符串.)

Mat*_*ens 11

字符串迭代器是唯一迭代代码点而不是UCS-2/UTF-16代码单元的东西.所以:

const string = 'Hi  Unicode!';
for (const symbol of string) {
  console.log(symbol);
}
Run Code Online (Sandbox Code Playgroud)

因此,要根据字符串中的索引获取特定代码点:

const string = 'Hi  Unicode!';
// Note: The spread operator uses the string iterator under the hood.
const symbols = [...string]; 
symbols[3]; // ''
Run Code Online (Sandbox Code Playgroud)

不过,这会打破石墨簇或表情符号序列,如???(+ U + 200D ZERO WIDTH JOINER ++ U + 200D ZERO WIDTH JOINER ++ U + 200D ZERO WIDTH JOINER +).文本分段有助于此.

你真的需要在字符串中获得第4个代码点吗?你的用例是什么?


小智 6

如果您可以使用新u标志,则可以将其用于正则表达式。

const chars = 'Hi  Unicode!'.match(/./ug);
console.log(chars);
Run Code Online (Sandbox Code Playgroud)