1 回答
TA贡献1852条经验 获得超7个赞
正如评论中已经提到的, 组合字符、修改符文和其他多符文 “字符” 可能会造成困难。
任何对 Go 中的 Unicode 处理感兴趣的人都应该阅读 Go 博客文章“ Go 中的 字符串、字节、符文和字符” 和“Go 中的文本规范化”。特别是,后者讨论了golang.org/x/text/unicode/norm
可以帮助处理其中一些问题的包。
您可以考虑从字符串中吐出第一个(或最后一个)“n 个字符”的几个级别越来越准确(或越来越多的 Unicode 感知)。
只需使用 n 个字节。这可能会在符文的中间分裂,但它是 O(1),非常简单,并且在许多情况下,您知道输入仅由单字节符文组成。例如
str[:n]
。在 n 个符文后分裂。这可能会在字符的中间分裂。这可以轻松完成,但代价是仅使用
string([]rune(str)[:n])
. 您可以通过使用unicode/utf8
包的DecodeRuneInString
(andDecodeLastRuneInString
) 函数依次获取前 n 个符文中的每个符文的长度,然后返回str[:sum]
(O(n),无分配)来避免转换和复制。在第 n 个“边界”之后拆分。一种方法是
norm.NFC.FirstBoundaryInString(str)
重复使用 或norm.Iter
找到要拆分的字节位置,然后返回str[:pos]
。
考虑显示的字符串“cafés”,它可以在 Go 代码中表示为:“cafés”、“caf\u00E9s”或“caf\xc3\xa9s”,它们都产生相同的六个字节。或者,它可以表示为“cafe\u0301s”或“cafe\xcc\x81s”,它们都产生相同的七个字节。
上面的第一个“方法”可能会将它们拆分为“caf\xc3”+“\xa9s”和cafe\xcc“+”\x81s”。
第二个可能将它们拆分为“caf\u00E9”+“s”(“cafe”+“s”)和“cafe”+“\u0301s”(“cafe”+“́s”)。
第三个应该将它们分成“caf\u00E9”+“s”和“cafe\u0301”+“s”(都显示为“café”+“s”)。
- 1 回答
- 0 关注
- 189 浏览
添加回答
举报