Javascript 如何反转包含复杂表情的字符串? 输入: helloworld

Javascript 如何反转包含复杂表情的字符串? 输入: helloworld,javascript,string,emoji,Javascript,String,Emoji,我决定做这件事只是为了好玩,这是一个很好的挑战。不确定它在所有情况下都是正确的,因此使用风险自负,但这里是: 函数运行(){ const text='Hello world我接受了TKoL使用\u200d字符的想法,并用它尝试创建一个较小的脚本 注意:并非所有构图都使用零宽度连接符,因此它将与其他构图字符混淆 它使用传统的for循环,因为如果我们发现组合的表情符号,我们会跳过一些迭代。在for循环中,有一个while循环来检查是否有以下\u200d字符。只要有一个,我们还会添加接下来的2个字符

我决定做这件事只是为了好玩,这是一个很好的挑战。不确定它在所有情况下都是正确的,因此使用风险自负,但这里是:

函数运行(){

const text='Hello world我接受了TKoL使用
\u200d
字符的想法,并用它尝试创建一个较小的脚本

注意:并非所有构图都使用零宽度连接符,因此它将与其他构图字符混淆

它使用传统的
for
循环,因为如果我们发现组合的表情符号,我们会跳过一些迭代。在
for
循环中,有一个
while
循环来检查是否有以下
\u200d
字符。只要有一个,我们还会添加接下来的2个字符,并用2次迭代,因此组合的表情符号不会反转

为了方便地在任何字符串上使用它,我将其作为字符串对象上的新原型函数

String.prototype.reverse=函数(){
让textArray=[…this];
让反向限制为“”;
for(设i=0;iconst text=“Hello world如果您能够,请使用提供的函数。从开始,
\uu.split()
能够拆分unicode表情

使用本机
.reverse().join(“”)
来反转“字符”,对于包含零宽度连接符的emoji应该可以正常工作

function reverse(txt){return uu.split(txt.),.reverse().join(“”);}

const text='Hello world我知道!我将使用RegExp。可能会出现什么问题?(答案留给读者作为练习。)


const text='Hello world您不仅在表情符号方面有困难,在其他组合字符方面也有困难。
这些感觉像单个字母但实际上是一个或多个unicode字符的东西被称为“扩展图形集”

将字符串拆分为这些集群是一件棘手的事情(例如,请参见这些)。我不会依靠自己实现它,而是使用一个现有的库。Google将我指向该库。该库的文档包含一些会使大多数实现失败的文档:

使用此选项,您应该能够编写:

var segmenter = new Intl.Segmenter("en", {granularity: "grapheme"})
var segment_iterator = segmenter.segment(string)
var graphemes = []
for (let {segment} of segment_iterator) {
    graphemes.push(segment)
}
var reversed = graphemes.reverse().join('');

旁白:对于来自未来的游客,或那些愿意生活在前沿的游客:

在javascript标准中添加一个grapheme分段器是一个很好的选择(它实际上还提供了其他分段选项)。 目前正在进行第3阶段的验收审查,目前正在JSC和V8中实施(请参阅)

使用此选项,代码将如下所示:

yourstring.split('').reverse().join('')
如果你比我懂得更多的现代javascript,你可能会使它更整洁

有一个-但我不知道它需要什么


注意:这指出了一个有趣的问题,其他答案尚未解决。分段可能取决于您使用的区域设置,而不仅仅是字符串中的字符。

替代解决方案是使用
符文库,这是一个小而有效的解决方案:

const符文=require('runes'))
//字符串。子字符串

“由于很多原因,反转Unicode文本是很棘手的

首先,根据编程语言的不同,字符串以不同的方式表示,可以是字节列表、UTF-16代码单元列表(16位宽,在API中通常称为“字符”),也可以是ucs4代码点(4个字节宽)

第二,不同的API在不同程度上反映了这种内部表示。有些用于字节的抽象,有些用于UTF-16字符,有些用于代码点。当表示使用字节或UTF-16字符时,API中通常有一些部分可以让您访问此表示的元素,还有一些部分可以执行rm从字节(通过UTF-8)或UTF-16字符到实际代码点的必要逻辑

通常,API中执行该逻辑并允许您访问代码点的部分是后来添加的,因为首先是7位ascii,然后是一段时间,每个人都认为8位就足够了,使用不同的代码页,甚至后来16位就够unicode了d上限在历史上被添加为逻辑编码文本的第四个公共字符长度

使用API使您能够访问实际的代码点似乎就是这样。但是

第三,有许多修饰语代码点影响下一个代码点或后续代码点。例如,有一个变音修饰语将后续的a变成a,E到ë,&c。将代码点转过来,aë变成Eë,由不同的字母组成。有一个直接表示Eë作为自己的代码点,但使用修饰语ier同样有效

第四,一切都在不断变化。在表情符号中也有很多修改器,如示例中所用,每年都会添加更多。因此,如果API允许您访问某个代码点是否为修改器的信息,则API的版本将确定它是否已经知道某个特定的新修改器

不过,Unicode提供了一个令人讨厌的技巧,当它只与视觉外观有关时:

有书写方向修饰符。在本例中,使用从左到右的书写方向。只需在文本开头添加一个从右到左的书写方向修饰符,并且根据API/浏览器的版本,它看起来会正确反转您可以使用:


它应该把你的字符串变成一个列表,把它倒过来,然后再把它变成一个字符串。

const text='Hello world我看不出第二个解决方案有什么问题。我遗漏了什么?所以这些表情实际上是组合符号
yourstring.split('').reverse().join('')