导读:本期聚焦于小伙伴创作的《Go语言里如何准确获取子字符串的字符Rune位置而不是字节位置》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Go语言里如何准确获取子字符串的字符Rune位置而不是字节位置》有用,将其分享出去将是对创作者最好的鼓励。

在Go语言中,字符串底层以UTF-8编码的字节序列存储。当文本包含中文、emoji等多字节字符时,如果直接使用bytes.Index返回的字节偏移来当作字符位置,会得到错误结果。要准确获取子字符串的字符也就是Rune位置,必须按Unicode码点来计数和查找。

Go语言里如何准确获取子字符串的字符Rune位置而不是字节位置

为什么字节位置不等于Rune位置

一个英文字母占1字节,而一个常用汉字占3字节。假设字符串为"Go语言",其字节长度为8,但Rune数量为4。若子串"语"从字节索引2开始,从字符角度看它却是第3个Rune(索引2)。

使用utf8包按Rune查找

可以先将字符串转为[]rune,再用strings.Index在rune切片上查找,从而得到字符位置:

package main

import (
    "fmt"
    "strings"
)

func runeIndex(s, sub string) int {
    // 将字符串转换为rune切片,每个元素是一个Unicode字符
    rs := []rune(s)
    // 子串也转换后,在rune切片中用字符串形式查找不便,这里借助strings.Index在原串找字节位置
    byteIdx := strings.Index(s, sub)
    if byteIdx == -1 {
        return -1
    }
    // 统计byteIdx之前的rune数量,即为子串的rune起始位置
    count := 0
    for i := 0; i < byteIdx; i++ {
        if (s[i] & 0xC0) != 0x80 {
            count++
        }
    }
    return count
}

func main() {
    s := "Go语言测试"
    fmt.Println(runeIndex(s, "语言")) // 输出2
}

利用range遍历获取Rune索引

Go的for range会自动按Rune迭代,并给出字节索引。我们可以用它建立字节到Rune位置的映射:

package main

import (
    "fmt"
    "strings"
)

func runePosOfSub(s, sub string) int {
    byteStart := strings.Index(s, sub)
    if byteStart < 0 {
        return -1
    }
    pos := 0
    for i := range s {
        if i == byteStart {
            return pos
        }
        pos++
    }
    return -1
}

func main() {
    fmt.Println(runePosOfSub("ab中文cd", "中文")) // 输出2
}

简单对比

方法优点注意点
转[]rune后查找直观,字符数即长度额外内存分配
bytes.Index加计数不转换整串需正确处理续字节
range映射语言原生支持需先获字节索引

小结

准确获取Go子字符串的Rune位置,核心在于区分字节与字符。实际开发中推荐先用strings.Index拿到字节位置,再通过range或utf8解码统计前面的Rune数,从而在文本处理、编辑器中定位真实字符位置。

Go语言子字符串Rune字符位置utf8修改时间:2026-07-25 11:00:19

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。