正确获取中文字符串的宽度
Get the width of Chinese strings correctly
我想在文本周围制作边框 这是一个测试
,但我无法获得它的实际宽度。对于英文文本,它确实可以完美运行。
这是我的分析:
len
告诉我这个:
这是一个测试 18
aaaaaaaaa 10
つのだ☆HIRO 16
aaaaaaaaaa 10
runewidth.StringWidth 告诉我这个:
这是一个测试 12
aaaaaaaaa 10
つのだ☆HIRO 11
aaaaaaaaaa 10
func main() {
fmt.Println("这是一个测试 |")
fmt.Println("aaaaaaaaaa | 10*a")
fmt.Println()
fmt.Println("这是一个测试 |")
fmt.Println("aaaaaaaaa | 9*a")
fmt.Println()
fmt.Println("Both are not equal to the Chinese text.")
fmt.Println("The (pipe) lines are not under each other.")
}
问题:
如何让我的盒子(第一个屏幕截图)正确显示?
Unicode 字符(如汉字)在 Golang 中占 3 个字节,而 ASCII 仅占 1 个字节。这是设计使然。
如果要检查unicode字符的实际字符串大小,请使用unicode/utf8内置包。
fmt.Printf("String: %s\nLength: %d\nRune Length: %d\n", c, len(c), utf8.RuneCountInString(c))
// String: 这是一个测试
// Length: 18
// Rune Length: 6
更基本的计数方法是使用 for 循环。
count := 0
for range "这是一个测试" {
count++
}
fmt.Printf("Count=%d\n", count)
// Count=6
关于表格格式的中英文字符串漂亮打印,好像没有直接的办法。在这种情况下,tabwriter 也不起作用。一个小技巧是使用 csv writer 如下:
data := [][]string{
{"这是一个测试", "|"},
{"aaaaaaaaaa", "|"},
{"つのだ☆HIRO", "|"},
{"aaaaaaaaaa", "|"},
}
w := csv.NewWriter(os.Stdout)
defer w.Flush()
w.Comma = '\t'
for _, row := range data {
w.Write(row)
}
这应该会按预期打印数据。不幸的是,Whosebug 打印的格式与我在终端中看到的格式不同。但是 Playground 可以拯救我们。 Click Here
Note
:这适用于符文大小彼此足够接近的字符串。对于更长的字符串,您需要更多的解决方法。
您的问题(如 )是一个 显示 问题,无法通过任何计数技巧解决。
当我们以英文显示可变间距或比例文本与 monospace 文本时,我们遇到了同样的问题。即比较:
mmmm, tasty
iiii, tasty?
与:
嗯嗯,好吃
三、好吃吗?
(假设您使用浏览器阅读此答案!)。我们不必打印汉字,甚至留下简单的ASCII都有问题!
您需要的是用于中文文本的等宽 显示字体 ,或者可能需要一些软件将其排版为表格形式,如何获得它是...另一个问题完全。
我想这就是你想要的
func TestChinese(t *testing.T) {
tests := []string{
"这是一个测试",
"aaaaaaaaa",
"つのだ☆HIRO",
"aaaaaaaaaa",
"这是aaaaa一个测试",
"这是一个つの测试",
}
for _, tt := range tests {
fmt.Printf("%s\t%d\t%d\n", tt, len([]rune(tt)), len([]byte(tt)))
}
}
输出:
这是一个测试 6 18
aaaaaaaaa 9 9
つのだ☆HIRO 8 16
aaaaaaaaaa 10 10
这是aaaaa一个测试 11 23
这是一个つの测试 8 24
我想在文本周围制作边框 这是一个测试
,但我无法获得它的实际宽度。对于英文文本,它确实可以完美运行。
这是我的分析:
len
告诉我这个:
这是一个测试 18
aaaaaaaaa 10
つのだ☆HIRO 16
aaaaaaaaaa 10
runewidth.StringWidth 告诉我这个:
这是一个测试 12
aaaaaaaaa 10
つのだ☆HIRO 11
aaaaaaaaaa 10
func main() {
fmt.Println("这是一个测试 |")
fmt.Println("aaaaaaaaaa | 10*a")
fmt.Println()
fmt.Println("这是一个测试 |")
fmt.Println("aaaaaaaaa | 9*a")
fmt.Println()
fmt.Println("Both are not equal to the Chinese text.")
fmt.Println("The (pipe) lines are not under each other.")
}
问题:
如何让我的盒子(第一个屏幕截图)正确显示?
Unicode 字符(如汉字)在 Golang 中占 3 个字节,而 ASCII 仅占 1 个字节。这是设计使然。
如果要检查unicode字符的实际字符串大小,请使用unicode/utf8内置包。
fmt.Printf("String: %s\nLength: %d\nRune Length: %d\n", c, len(c), utf8.RuneCountInString(c))
// String: 这是一个测试
// Length: 18
// Rune Length: 6
更基本的计数方法是使用 for 循环。
count := 0
for range "这是一个测试" {
count++
}
fmt.Printf("Count=%d\n", count)
// Count=6
关于表格格式的中英文字符串漂亮打印,好像没有直接的办法。在这种情况下,tabwriter 也不起作用。一个小技巧是使用 csv writer 如下:
data := [][]string{
{"这是一个测试", "|"},
{"aaaaaaaaaa", "|"},
{"つのだ☆HIRO", "|"},
{"aaaaaaaaaa", "|"},
}
w := csv.NewWriter(os.Stdout)
defer w.Flush()
w.Comma = '\t'
for _, row := range data {
w.Write(row)
}
这应该会按预期打印数据。不幸的是,Whosebug 打印的格式与我在终端中看到的格式不同。但是 Playground 可以拯救我们。 Click Here
Note
:这适用于符文大小彼此足够接近的字符串。对于更长的字符串,您需要更多的解决方法。
您的问题(如
当我们以英文显示可变间距或比例文本与 monospace 文本时,我们遇到了同样的问题。即比较:
mmmm, tasty
iiii, tasty?
与:
嗯嗯,好吃
三、好吃吗?
(假设您使用浏览器阅读此答案!)。我们不必打印汉字,甚至留下简单的ASCII都有问题!
您需要的是用于中文文本的等宽 显示字体 ,或者可能需要一些软件将其排版为表格形式,如何获得它是...另一个问题完全。
我想这就是你想要的
func TestChinese(t *testing.T) {
tests := []string{
"这是一个测试",
"aaaaaaaaa",
"つのだ☆HIRO",
"aaaaaaaaaa",
"这是aaaaa一个测试",
"这是一个つの测试",
}
for _, tt := range tests {
fmt.Printf("%s\t%d\t%d\n", tt, len([]rune(tt)), len([]byte(tt)))
}
}
输出:
这是一个测试 6 18
aaaaaaaaa 9 9
つのだ☆HIRO 8 16
aaaaaaaaaa 10 10
这是aaaaa一个测试 11 23
这是一个つの测试 8 24