编辑#2:您再次指出了问题的一种新类型“含义”:您想string
在 a 中搜索 a []rune
。
答:标准库中不直接支持。for
但是用 2 个循环很容易实现它:
func search(text []rune, what string) int {
whatRunes := []rune(what)
for i := range text {
found := true
for j := range whatRunes {
if text[i+j] != whatRunes[j] {
found = false
break
}
}
if found {
return i
}
}
return -1
}
测试它:
value := []rune("123}456}}789")
result := search(value, "}}")
fmt.Println(result)
输出(在Go Playground上试试):
7
编辑:您更新了表明您要在 a 中搜索rune
s 的问题string
。
您可以使用简单的类型转换轻松地将 a 转换[]rune
为 a :string
toSearchRunes := []rune{'}', '}'}
toSearch := string(toSearchRunes)
从那里开始,您可以strings.Index()
像在示例中那样使用:
if i := strings.Index(text[offset:], toSearch); i > 0 {
print(i)
}
在Go Playground上尝试一下。
原答案如下:
string
Go 中的值存储为 UTF-8 编码字节。strings.Index()
如果找到给定的子字符串,则返回字节位置。
所以基本上你想要的是将这个字节位置转换为符文位置。该unicode/utf8
软件包包含用于告诉符文计数或符文长度的实用函数string
: utf8.RuneCountInString()
。
所以基本上你只需要将子字符串传递给这个函数:
offset := 0
text := "123456789}}56"
if i := strings.Index(text[offset:], "}}"); i > 0 {
fmt.Println("byte-pos:", i, "rune-pos:", utf8.RuneCountInString(text[offset:i]))
}
text = "世界}}世界"
if i := strings.Index(text[offset:], "}}"); i > 0 {
fmt.Println("byte-pos:", i, "rune-pos:", utf8.RuneCountInString(text[offset:i]))
}
输出(在Go Playground上试试):
byte-pos: 9 rune-pos: 9
byte-pos: 6 rune-pos: 2
注意:offset
也必须是字节位置,因为在对string
like进行切片时text[offset:]
,索引被解释为字节索引。
如果要获取 a 的索引rune
,请使用strings.IndexRune()
而不是strings.Index()
.