string - 正确获取中文字符串的宽度

标签 string go terminal rune

我想在文本周围制作边框这是一个测试,但我无法获得它的实际宽度。对于英文文本,它确实可以完美运行。

Screenshot

这是我的分析:

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.")
}

enter image description here

问题:

如何让我的盒子(第一个屏幕截图)正确显示?

最佳答案

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

关于表格格式的中英文字符串 pretty-print ,好像没有直接的办法。在这种情况下,tabwriter 也不起作用。一个小的 hack-around 是使用 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)
}

这应该按预期打印数据。不幸的是,StackOverflow 打印的格式与我在终端中看到的格式不同。但是 Playground 可以拯救我们。 Click Here

注意:这适用于 rune 大小彼此足够接近的字符串。对于更长的字符串,您需要更多的解决方法。

关于string - 正确获取中文字符串的宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69559133/

相关文章:

java - 将带有分隔符的字符串解析为数组

java - 如何在 Java 中比较字符串?

mongodb - 如何在 mongodb 中创建数据库结构以保存日期范围?

go - gRPC客户端不占用服务器端流

pointers - 如何修改结构指针类型的接口(interface)值

Vim:配色方案在终端中无法正确显示

Python3 使用字典替换

python - 字符串与特定变量字符的组合

linux - 在文本文件文件中搜索数字并指定范围和长度 Grep

ios - 添加 OpenCV-Dynamic cocoapod 的问题