结合字符(字形群集)和MS Windows控制台cmd.exe的Unicode

时间:2018-08-24 14:09:53

标签: go unicode windows-10 windows-console

在以下代码中,不是单个Unicode字符U + 00FC,而是一个由两个Unicode字符组成的单个字素簇,即纯ASCII u U + 0075,然后进行组合透尿U + 0308。

fmt.Println("Jürgen Džemal")
fmt.Println("Ju\u0308rgen \u01c5emel")

如果我运行in the go playground,它将按预期运行。

如果我在MS Windows 10“命令提示符”窗口中运行它,则它不会在视觉上将合并字符与先前字符组合在一起。 但是,当我将文本剪切并粘贴到此处时,它会正确显示:

C:\> ver

Microsoft Windows [Version 10.0.17134.228]

C:\> test
Jürgen Džemal
Jürgen Džemel

在屏幕上的“命令提示符”窗口中,它看起来更像:

Ju¨rgen Džemel

将代码页(chcp)从850更改为65001没什么区别。更改字体(Consolas,Courier等)没有影响。

过去,我遇到的问题基本上是因为Microsoft要求Windows程序使用不同的API将字符输出到STDOUT,具体取决于STDOUT是连接到控制台还是文件。我不知道这是否是同一问题的不同表现。

我可以做些什么来使此Unicode字形群集正确显示吗?

1 个答案:

答案 0 :(得分:3)

eryksunPeter所评论,

  • Windows控制台(conhost.exe)不支持组合代码。您必须首先将其标准化为使用预先组成的字符的等效字符串。
  • 您可以使用golang.org/x/text/unicode/norm进行规范化(例如norm.NFC.String("Jürgen Džemal")

我尝试过

s := "Ju\u0308rgen \u01c5emel"
fmt.Println(s)              // dieresis not combined with u by conhost.exe
s = norm.NFC.String(s)
fmt.Println(s)              // shows correctly

输出看起来像这样

Ju¨rgen Džemel \n Jürgen Džemel

或者,对于那些视力受损的人来说,它们是非常复杂的屏幕阅读器-有点像这样:

Ju¨rgen Džemel
Jürgen Džemel

请注意,Unicode具有四种不同的规范化形式,但是NFC是Internet上网页上使用最多的一种,也适用于这种情况。

此程序包中还有其他方法可能更有效或更有用

我阅读了一些正在使用的视觉字符,这些视觉字符只能使用组合字符以Unicode表示。换句话说,没有预组合的字符。需要一种更彻底的方法来对它们进行适当的处​​理。本质上,Unicode(或者更准确地说是人类语言及其印刷术)的复杂性几乎是没有止境的。在我看来有时似乎是这样。

参考