出于很多原因,反转Unicode文本非常棘手。
首先,根据编程语言的不同,字符串以不同的方式表示:字节列表,UTF-16代码单元列表(16位宽,在API中通常称为“字符”)或ucs4代码点(4个字节宽)。
其次,不同的API在不同程度上反映了内部表示。一些工作于字节的抽象,一些工作于UTF-16字符,一些工作于代码点。当表示形式使用字节或UTF-16字符时,API的通常部分使您可以访问此表示形式的元素,以及执行必要的逻辑以从字节(通过UTF-8)或UTF-16字符为实际代码点。
通常,稍后会添加API中执行该逻辑的部分,从而使您可以访问代码点,因为首先使用7位ascii,然后再后来,每个人都认为8位就足够了,使用不同的代码页,甚至后来那16位足以容纳unicode。历史上,代码点的概念是无固定上限的整数,作为逻辑编码文本的第四公共字符长度被添加。
使用使您可以访问实际代码点的API就是这样。但...
第三,有很多修饰语代码点会影响下一个代码点或后续代码点。例如,有一个变音符修饰符,将跟随a转换为ä,e到ë,&c。翻转代码点,然后由不同字母组成的aë变为eä。有一个直接表示例如ä的代码点,但是使用修饰符同样有效。
第四,一切都在不断变化。如示例中所使用,表情符号中也有很多修饰符,并且每年还会添加更多的修饰符。因此,如果API使您可以访问信息,则代码点是否为修饰符,则API版本将确定它是否已经知道特定的新修饰符。
但是,Unicode仅在外观上提供了一个技巧:
有书写方向修饰符。在该示例的情况下,使用从左到右的书写方向。只需在文本的开头添加一个从右到左的书写方向修饰符,并且根据API /浏览器的版本,它将看起来正确反转😎
'\ u202e'被称为从右到左覆盖,它是从右到左标记的最强版本。
请参阅w3.org的解释
const text = 'Hello world👩🦰👩👩👦👦'
console.log('\u202e' + text)
const text = 'Hello world👩🦰👩👩👦👦'
let original = document.getElementById('original')
original.appendChild(document.createTextNode(text))
let result = document.getElementById('result')
result.appendChild(document.createTextNode('\u202e' + text))
body {
font-family: sans-serif
}
<p id="original"></p>
<p id="result"></p>