是否有一些优雅的方法来裁剪字符串并在golang中创建漂亮的字符串前缀?我有这个功能开始:
func prettyCrop(in string, cropLength int) string {
if len(in) < cropLength {
return in
} else {
in = in[0:cropLength]
in = strings.TrimRightFunc(in, func(r rune) bool {
if r == ' ' {
return true
}
return false
})
return in + "…"
}
}
它对于英文文本来说已经足够好了,但是有一些更复杂的问题。见这个例子:
prettyCrop("čřč čřč", 8) //čř?…
TrimRightFunc无法正常工作。我希望它返回čřč
。为什么这个函数没有返回有效的utf-8字符串?有这个图书馆吗?我该如何解决?有更好的解决方案吗?
答案 0 :(得分:2)
问题是切片string
切片表示字符串的UTF-8编码字节切片,而不是rune
的字符或string
;这也意味着如果string
包含由UTF-8编码中的多个字节表示的字符,则切片/切割string
可能会导致UTF-8编码序列无效。
假设cropLength
表示字符数限制(而不是字节数限制),您应首先将string
转换为[]rune
,然后对其进行操作:
func prettyCrop(in string, cropLength int) string {
in2 := []rune(in)
if len(in2) < cropLength {
return in
} else {
in2 = in2[:cropLength]
in = strings.TrimRightFunc(string(in2), func(r rune) bool {
if r == ' ' {
return true
}
return false
})
return in + "…"
}
}
测试它:
for i := 0; i < 7; i++ {
fmt.Println(prettyCrop("čřč čřč", i))
}
输出(在Go Playground上尝试):
…
č…
čř…
čřč…
čřč…
čřč č…
čřč čř…
效果说明:
以上示例并非“友好”,因为:
in
字符串转换为[]rune
,只需使用cropLength
获取其第一个for range
符文即可。strings.TrimRightFunc()
需要将[]rune
转换回string
,然后再次执行字符串连接以生成结果。这可以通过手动循环[]rune
来避免,并且只创建一个返回的string
。