golang获取字符或字符串固定宽度计算插件库go-runewidth的使用
golang获取字符或字符串固定宽度计算插件库go-runewidth的使用
go-runewidth 是一个用于获取字符或字符串固定宽度的Golang库,特别适合处理包含全角字符、emoji等不同宽度字符的场景。
功能特点
- 计算字符串在终端显示时的实际宽度
- 正确处理全角字符(如中文、日文等)
- 支持emoji等特殊字符的宽度计算
安装方法
go get github.com/mattn/go-runewidth
使用示例
基本用法
package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
// 计算字符串宽度
width := runewidth.StringWidth("つのだ☆HIRO")
fmt.Println(width) // 输出: 12
// 计算中文字符串宽度
chineseWidth := runewidth.StringWidth("你好世界")
fmt.Println(chineseWidth) // 输出: 8
// 计算包含emoji的字符串宽度
emojiWidth := runewidth.StringWidth("Hello 😊")
fmt.Println(emojiWidth) // 输出: 7
}
更完整的示例
package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
// 测试各种字符的宽度
testStrings := []string{
"Hello", // 全半角字符
"こんにちは", // 日文
"안녕하세요", // 韩文
"你好", // 中文
"Hello 😊", // 包含emoji
"12345", // 数字
"!@#$%", // 符号
}
for _, s := range testStrings {
width := runewidth.StringWidth(s)
fmt.Printf("字符串: %s\n实际宽度: %d\n字符数: %d\n\n", s, width, len(s))
}
// 计算单个字符的宽度
rune1 := 'A'
rune2 := 'あ'
rune3 := '😊'
fmt.Printf("字符 '%c' 的宽度: %d\n", rune1, runewidth.RuneWidth(rune1)) // 1
fmt.Printf("字符 '%c' 的宽度: %d\n", rune2, runewidth.RuneWidth(rune2)) // 2
fmt.Printf("字符 '%c' 的宽度: %d\n", rune3, runewidth.RuneWidth(rune3)) // 2
}
高级用法:字符串截断
package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
// 将字符串截断到指定宽度
str := "これはテストですThis is a test"
// 截断到宽度10
truncated := runewidth.Truncate(str, 10, "...")
fmt.Println(truncated) // 输出: これは... (实际显示宽度为10)
// 填充字符串到指定宽度
padded := runewidth.FillRight("Hello", 10) + "|"
fmt.Println(padded) // 输出: "Hello |" (总宽度10)
padded = runewidth.FillLeft("Hello", 10) + "|"
fmt.Println(padded) // 输出: " Hello|" (总宽度10)
}
注意事项
- 全角字符(如中文、日文等)的宽度通常为2
- 大多数emoji的宽度为2
- 普通ASCII字符的宽度为1
作者
Yasuhiro Matsumoto
许可证
MIT License
更多关于golang获取字符或字符串固定宽度计算插件库go-runewidth的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang获取字符或字符串固定宽度计算插件库go-runewidth的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
go-runewidth 使用指南
go-runewidth 是一个用于计算字符串显示宽度的 Go 语言库,特别适合处理多字节字符(如中文、日文等)的宽度计算。它能够正确处理全角字符(通常占2个显示宽度)和半角字符(通常占1个显示宽度)。
安装
go get github.com/mattn/go-runewidth
基本用法
1. 获取字符串显示宽度
package main
import (
"fmt"
"github.com/mattn/go-runewidth"
)
func main() {
// 计算字符串的显示宽度
str := "Hello, 世界"
width := runewidth.StringWidth(str)
fmt.Printf("'%s' 的显示宽度: %d\n", str, width)
// 输出: 'Hello, 世界' 的显示宽度: 11
// 解释: "Hello, " 7个半角字符(7) + "世界" 2个全角字符(4) = 11
}
2. 截断字符串到指定宽度
func main() {
str := "Hello, 世界"
// 截断字符串到指定宽度
truncated := runewidth.Truncate(str, 8, "...")
fmt.Printf("截断到8宽度: '%s'\n", truncated)
// 输出: 截断到8宽度: 'Hello, 世...'
truncated2 := runewidth.Truncate(str, 9, "...")
fmt.Printf("截断到9宽度: '%s'\n", truncated2)
// 输出: 截断到9宽度: 'Hello, 世界'
}
3. 填充字符串到指定宽度
func main() {
str := "你好"
// 填充字符串到指定宽度
padded := runewidth.FillRight(str, 10) // 右侧填充空格
fmt.Printf("填充到10宽度(右): '%s'\n", padded)
// 输出: 填充到10宽度(右): '你好 '
paddedLeft := runewidth.FillLeft(str, 10) // 左侧填充空格
fmt.Printf("填充到10宽度(左): '%s'\n", paddedLeft)
// 输出: 填充到10宽度(左): ' 你好'
}
4. 处理制表符宽度
func main() {
str := "Hello\t世界"
// 计算字符串宽度,考虑制表符
width := runewidth.StringWidth(str)
fmt.Printf("原始宽度: %d\n", width)
// 展开制表符
expanded := runewidth.ExpandTabs(str, 8)
fmt.Printf("展开制表符: '%s'\n", expanded)
expandedWidth := runewidth.StringWidth(expanded)
fmt.Printf("展开后宽度: %d\n", expandedWidth)
}
5. 处理emoji等特殊字符
func main() {
emoji := "🚀火箭"
width := runewidth.StringWidth(emoji)
fmt.Printf("'%s' 的显示宽度: %d\n", emoji, width)
// 输出: '🚀火箭' 的显示宽度: 6
// 解释: "🚀" 通常算作2宽度 + "火箭" 4宽度 = 6
}
高级用法
自定义字符宽度处理
func main() {
// 默认情况下,中文是2宽度
str := "中文"
fmt.Printf("默认宽度: %d\n", runewidth.StringWidth(str)) // 4
// 可以创建自定义条件
condition := runewidth.NewCondition()
condition.EastAsianWidth = false // 不按东亚宽度处理
fmt.Printf("非东亚宽度: %d\n", condition.StringWidth(str)) // 2
}
处理终端输出对齐
func main() {
items := []struct {
name string
price string
}{
{"苹果", "¥5"},
{"香蕉", "¥3"},
{"火龙果", "¥10"},
}
// 计算名称列最大宽度
maxNameWidth := 0
for _, item := range items {
w := runewidth.StringWidth(item.name)
if w > maxNameWidth {
maxNameWidth = w
}
}
// 打印对齐的表格
for _, item := range items {
padding := maxNameWidth - runewidth.StringWidth(item.name)
fmt.Printf("%s%s\t%s\n", item.name, strings.Repeat(" ", padding), item.price)
}
/* 输出:
苹果 ¥5
香蕉 ¥3
火龙果 ¥10
*/
}
注意事项
- 全角字符(如中文、日文等)通常计为2个显示宽度,半角字符计为1个
- 某些特殊字符(如emoji)的宽度可能因终端而异
- 制表符的宽度取决于制表位设置(通常为8个字符宽度)
- 组合字符(如带音标的字母)可能会影响宽度计算
go-runewidth 是构建命令行工具时处理多语言字符串对齐和格式化的理想选择,特别适合需要精确控制终端输出的场景。