我知道Á
的unicode代码点是U+00C1
。我在网上和很多论坛上读到,我也可以通过组合字符´
(unicode:U+00B4
)和A
(unicode=U+0041
)来制作Á
。
我的问题很简单。怎么做?我试过这样的东西我决定在golang中尝试,但如果有人知道如何在python(或其他编程语言)中进行,那就完全可以了。这对我来说并不重要。
好吧,所以我下一步试试。
二进制中的A
为:01000001
二进制中的´
为:10110100
它总共需要15位,所以我需要UTF-8 3字节格式(1110xxxx 10xxxxxx 10xxxxxx
)
通过在x的位置填充来自A
和´
(第一个A)的比特,得到以下内容:11100100 10000110 10110100
。
然后,我将得到的三个字节转换回十六进制值:E4 86 B4
。
然而,当我尝试用代码编写它时,我得到了一个完全不同的字符。换句话说,我的解决方案并没有像我预期的那样起作用。
package main
import (
"fmt"
)
func main() {
r := "xE4x86xB4"
fmt.Println(r) // It wrote 䆴 instead of Á
}
您提供的´
(U+00B4)字符实际上并不是Unicode定义的组合字符。
>>> "Au00b4"
'A´'
如果我们使用◌́
(U+0301),那么我们可以将它与A
这样的字符按顺序放置,并获得预期的输出:
>>> "Au0301"
'Á'
除非我误解了你的意思,否则这里似乎不需要任何二进制操作或欺骗。
正如StardustGogeta在他们的答案中解释的那样;急性;重音为U+0301(组合用锐音符)。
但在Go中,由单个U+00C1(带锐音符的拉丁文大写字母a)字符组成的字符串不等于由U+0041(拉丁文大写字母B)后跟U+0301(组合用锐音符)组成的字符串
如果你想比较字符串,你需要将两者规范化为相同的规范化形式。有关更多详细信息,请参阅Go中的博客文章文本规范化。
下面的代码片段展示了如何做到这一点:
package main
import (
"fmt"
"golang.org/x/text/unicode/norm"
)
func main() {
combined := "u00c1"
combining := "Au0301"
fmt.Printf("combined = %s, combining = %sn", combined, combining)
fmt.Printf("combined == combining: %tn", combined == combining)
combiningNormalised := string(norm.NFC.Bytes([]byte(combining)))
fmt.Printf("combined == combiningNormalised: %tn", combined == combiningNormalised)
}
输出:
combined = Á, combining = Á
combined == combining: false
combined == combiningNormalised: true