你可以试试RuneCountInString http://golang.org/pkg/unicode/utf8/#RuneCountInString来自 utf8 包。
返回 p 中的符文数量
即,如图所示这个脚本 http://play.golang.org/p/zzB1VrwdER:“World”的长度可能是6(中文写成“世界”),但“世界”的符文数是2:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
Phrozen https://stackoverflow.com/users/383848/phrozen adds 在评论中 https://stackoverflow.com/questions/12668681/go-language-string-length/12668840#comment39875126_12668840:
其实你可以做len()
仅通过类型转换来覆盖符文。
len([]rune("世界"))
将打印2
。至少在 Go 1.3 中是这样。
与CL 108985 https://go-review.googlesource.com/c/go/+/108985(2018 年 5 月,Go 1.11),len([]rune(string))
现已优化。 (修复问题 24923 https://github.com/golang/go/issues/24923)
编译器检测到len([]rune(string))
自动模式,并将其替换为 for r := range s 调用。
添加一个新的运行时函数来计算字符串中的符文数量。
修改编译器以检测模式len([]rune(string))
并将其替换为新的符文计数运行时函数。
RuneCount/lenruneslice/ASCII 27.8ns ± 2% 14.5ns ± 3% -47.70%
RuneCount/lenruneslice/Japanese 126ns ± 2% 60 ns ± 2% -52.03%
RuneCount/lenruneslice/MixedLength 104ns ± 2% 50 ns ± 1% -51.71%
斯特凡·施泰格 https://stackoverflow.com/users/155077/stefan-steiger指向博客文章“Go 中的文本规范化 https://blog.golang.org/normalization"
什么是角色?
正如在字符串博客文章 http://blog.golang.org/strings, 字符可以跨越多个符文.
例如,一个 'e
' 和 '◌́◌́'(锐音“\u0301”)可以组合形成 'é'(“e\u0301
“在 NFD 中)。这两个符文合在一起就是一个字符.
字符的定义可能因应用程序而异。
For 正常化 https://godoc.org/golang.org/x/text/unicode/norm我们将其定义为:
- 以启动器开始的一系列符文,
- 不会修改或与任何其他符文向后组合的符文,
- 接下来是可能为空的非起始序列,即符文(通常是重音符号)。
标准化算法一次处理一个字符。
使用该包及其Iter type https://godoc.org/golang.org/x/text/unicode/norm#Iter,“字符”的实际数量为:
package main
import "fmt"
import "golang.org/x/text/unicode/norm"
func main() {
var ia norm.Iter
ia.InitString(norm.NFKD, "école")
nc := 0
for !ia.Done() {
nc = nc + 1
ia.Next()
}
fmt.Printf("Number of chars: %d\n", nc)
}
在这里,这使用了Unicode 规范化形式 http://unicode.org/reports/tr15/#Norm_FormsNFKD《兼容性分解》
Oliver https://stackoverflow.com/users/2046109/oliver's answer https://stackoverflow.com/a/55151396/6309指着UNICODE 文本分割 http://unicode.org/reports/tr29/作为可靠地确定某些重要文本元素(用户感知的字符、单词和句子)之间的默认边界的唯一方法。
为此,您需要一个外部库,例如里沃/尤尼塞格 https://github.com/rivo/uniseg,这确实Unicode 文本分割.
这实际上会算“grapheme https://en.wikipedia.org/wiki/Grapheme cluster”,其中多个代码点可以组合成一个用户感知的字符。
package uniseg
import (
"fmt"
"github.com/rivo/uniseg"
)
func main() {
gr := uniseg.NewGraphemes("????????!")
for gr.Next() {
fmt.Printf("%x ", gr.Runes())
}
// Output: [1f44d 1f3fc] [21]
}
两个字素,尽管有三个符文(Unicode 代码点)。
您可以在“中查看其他示例”如何操作GO中的字符串来反转它们? https://stackoverflow.com/a/62743214/6309"
???????????? 单独是一个字素,但是,从unicode 到代码点转换器 https://onlineunicodetools.com/convert-unicode-to-code-points, 4 个符文:
- ????: 女性 (1f469) https://apps.timwhitlock.info/unicode/inspect/hex/1F469
- 深色皮肤 (1f3fe) https://apps.timwhitlock.info/unicode/inspect/hex/1f3fe
- 零宽度连接器 (200d) https://apps.timwhitlock.info/unicode/inspect/hex/200d
- ????红发 (1f9b0) https://apps.timwhitlock.info/unicode/inspect/hex/1f9b0