如何获取字符串中的字符数 [英] How to get the number of characters in a string
问题描述
如何获取围棋中字符串的字符数?
例如,如果我有一个字符串"hello"
,该方法应该返回5
。我看到len(str)
返回字节数而不是字符数,因此len("£")
返回2而不是1,因为GB在UTF-8中是用两个字节编码的。
推荐答案
您可以从utf8包中尝试RuneCountInString
。
返回p中的符号数
如this script所示:世界和世界的长度可能为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))
现已优化。(修复issue 24923)
编译器自动检测len([]rune(string))
模式,并将其替换为for r:=range的调用。
添加了一个新的运行时函数来计算字符串中的符文。 修改编译器以检测模式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%
Stefan Steiger指向博客帖子Text normalization in Go
什么是字符?
如strings blog post中所述,字符可以跨越多个符文。
例如,"e
"和"◌́◌́"(急性&u0301&qot;)可以组合成"é"(";eu0301
";in nfd)。这两个符文加在一起是一个字符。字符的定义可能因应用程序而异。
对于normalization,我们将其定义为:
- 以起始符开头的符文序列
- 不修改或向后组合任何其他符文的符文
- 后跟可能为空的非启动符序列,即具有启动符的符文(通常是重音符号)。
规范化算法一次处理一个字符。
使用该软件包及其Iter
type,实际";字符数为:
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
", nc)
}
此处,它使用Unicode Normalization formNFKD&Quot;兼容性分解
Oliver的answer指向UNICODE TEXT SEGMENTATION是可靠地确定某些重要文本元素(用户可感知的字符、单词和句子)之间默认边界的唯一方法。
为此,您需要一个像rivo/uniseg这样的外部库,它执行Unicode文本分割。
这将实际计算";grapheme群集";,其中多个代码点可以组合成一个用户可识别的字符。
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代码点)。
您可以在";How to manipulate strings in GO to reverse them?";
中查看其他示例仅👩🏾🦰一项就是一个字素,但来自unicode to code points converter的是4个符文:
这篇关于如何获取字符串中的字符数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!