Go语言如何查找并统计字符串中的带重音符号字符?
问题根因
Go的字符串原生采用UTF-8编码,len()对字符串求值时返回的是字节长度,不是可见字符的数量。
ASCII范围内的普通字符每个仅占1字节,按字节索引word[i]取值再比对的逻辑可以正常运行;但重音字符、其他非ASCII特殊字符在UTF-8中大多占2-4字节,此时按字节索引取到的只是字符拆分后的单个字节片段,并非完整的目标字符,自然永远无法匹配,计数器始终返回0。
可行解决方案
方案1:for range 直接遍历(推荐)
Go原生的for range循环遍历字符串时,会自动按UTF-8规则解码,每次迭代拿到的都是完整的Unicode码点(rune类型),不需要额外做类型转换,写法最简洁:
package main import "fmt" func main() { word := "cèòài" letter := "è" var counter int // 先把单字符的letter转为rune类型,方便后续比对 target := []rune(letter)[0] for _, r := range word { if r == target { counter++ } } fmt.Print(counter) // 运行输出1,结果符合预期 }
方案2:显式转rune切片后遍历
如果需要按字符位置做索引操作,可以先把整个字符串转为[]rune切片,此时切片的长度就是实际字符数,按索引取到的元素都是完整字符:
package main import "fmt" func main() { word := "cèòài" letter := "è" var counter int runeWord := []rune(word) target := []rune(letter)[0] for i := 0; i < len(runeWord); i++ { if runeWord[i] == target { counter++ } } fmt.Print(counter) }
补充注意:如果遇到视觉上完全相同的重音字符仍然匹配失败,大概率是Unicode编码形式不一致导致的——同一个重音字符可能存在「单码点直接存储」和「普通字母+组合重音符号」两种编码形式,这种情况需要先对两个字符串做Unicode归一化处理后再做比对。
内容的提问来源于stack exchange,提问作者Logan
相关产品推荐
相关产品推荐

