如何在Go中获取字符串的字符数?
例如,如果我有一个字符串,则"hello"
该方法应返回5
。我看到len(str)
返回的字节数 ,而不是
字符的数量,以便len("£")
返回2而不是1,因为£被编码有在UTF-8的两个字节。
您可以RuneCountInString
从utf8包中尝试。
返回p中的符文数
如该脚本所示:“世界”的长度可能为6(用中文写成“世界”),但符文数为2:
package main
import "fmt"
import "unicode/utf8"
func main() {
fmt.Println("Hello, 世界", len("世界"), utf8.RuneCountInString("世界"))
}
实际上len()
,只需键入强制转换即可完成符文。 len([]rune("世界"))
将打印2
。在Go 1.3中。
借助CL 108985(2018年5月,适用于Go
1.11),len([]rune(string))
现已进行了优化。(修复了问题24923)
编译器len([]rune(string))
自动检测模式,并将其替换为r:= range调用。
添加一个新的运行时函数以计算字符串中的符文。修改编译器以检测模式,
len([]rune(string))
并将其替换为新的符文计数运行时函数。
RuneCount/lenruneslice/ASCII 27.8ns ± 2% 14.5ns ± 3% -47.70% (p=0.000 n=10+10)
RuneCount/lenruneslice/Japanese 126ns ± 2% 60ns ± 2% -52.03% (p=0.000 n=10+10)
RuneCount/lenruneslice/MixedLength 104ns ± 2% 50ns ± 1% -51.71% (p=0.000 n=10+9)
Stefan Steiger指向博客文章“
Go中的文本规范化 ”
什么是角色?
正如字符串博客文章中提到的那样, 角色可以跨越多个符文 。
例如,一个’e
‘和’◌́◌́’(急性“ \ u0301”)可以组合成一个’é’(e\u0301
在NFD中为“ ”)。
这两个符文合在一起是一个角色 。字符的定义可能会因应用程序而异。
为了 规范化, 我们将其定义为:
- 以起动器开始的一系列符文,
- 不会修改或向后组合任何其他符文的符文,
- 随后可能是空的非启动器序列,即具有此功能的符文(通常为重音符号)。
归一化算法一次处理一个字符。
使用该软件包及其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规范化形式 NFKD“兼容性分解”
Oliver的答案指出
UNICODE TEXT SEGMENTATION
是可靠确定某些重要文本元素(用户感知的字符,单词和句子)之间默认边界的唯一方法。
为此,您需要一个像 rivo / uniseg 这样的外部库,它可以执行
Unicode Text Segmentation 。
将实际计数“ 字形 簇
”,其中多个码点可被组合成一个用户感知的字符。
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代码点),也有两个字素。