如何在golang中从一个rune字符串中获取子字符串?

14

我发现了这个链接,但据我所知,这些解决方案对我无效。

如果您使用将字符串视为切片的方法(str[:20]),则会在字符中间断开,我们得到“ال�”。

编辑:我相信我可以编写一个函数,并将其作为rune的3的倍数来执行,因为rune是int32(32位/(8位/字节))。 我首先必须检查是否存在rune。

4个回答

33

首先将其转换为符文切片,然后对该切片进行操作,最后将结果转换回去:

string([]rune(str)[:20])

3
请注意,如果字符串大小已经不足以进行您尝试裁剪的操作,则可能会出现以下错误:panic: runtime error: slice bounds out of range - dr.scre
这样做需要O(len(str))的时间,因此最好将字符串保留在[]rune表示中,直到您再次需要它以可变宽度字符串形式。 - Michael Fulton
警告:这可能会修改子字符串末尾的字符,因为一个字符可以由多个符文组成,例如 https://go.dev/play/p/6u7gx1CQxTW - Jason Stangroome

14

您可以在不分配额外内存的情况下获取UTF-8字符串的子串(无需将其转换为rune切片):

func substring(s string, start int, end int) string {
    start_str_idx := 0
    i := 0
    for j := range s {
        if i == start {
            start_str_idx = j
        }
        if i == end {
            return s[start_str_idx:j]
        }
        i++
    }
    return s[start_str_idx:]
}

func main() {
    s := "世界 Hello"
    fmt.Println(substring(s, 0, 1)) // 世
    fmt.Println(substring(s, 1, 5)) // 界 He
    fmt.Println(substring(s, 3, 8)) // Hello
}

3

这是一个基于rune技巧的长度实现:

最初的回答

func substr(input string, start int, length int) string {
    asRunes := []rune(input)

    if start >= len(asRunes) {
        return ""
    }

    if start+length > len(asRunes) {
        length = len(asRunes) - start
    }

    return string(asRunes[start : start+length])
}

2
如果您不介意使用实验性软件包,可以使用以下内容:
package main
import "golang.org/x/exp/utf8string"

func main() {
   a := utf8string.NewString("ÄÅàâäåçèéêëìîïü")
   s := a.Slice(1, 3)
   println(s == "Åà")
}

https://pkg.go.dev/golang.org/x/exp/utf8string


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接