如何在Go语言中使用rune找到字符串的偏移索引

huangapple go评论86阅读模式
英文:

How found offset index a string in rune using go

问题

如何在Go语言中使用[]rune找到字符串中的偏移索引?

我可以使用字符串类型来完成这个任务。

if i := strings.Index(input[offset:], "}}"); i > 0 {print(i);}

但是我需要使用[]rune类型。

我有一个[]rune,并且想要获取偏移索引。

在Go语言中,如何使用[]rune类型完成这个任务?

以下是一个更好理解需求的示例:

int offset=0//表示从0开始(这对我很重要)
string text="123456783}}56"
if i := strings.Index(text[offset:], "}}"); i > 0 {print(i);}

这个示例的输出是:9

但是我想要使用[]rune类型来完成这个任务(使用text变量)。

可以吗?

请查看我的当前代码:https://play.golang.org/p/seImKzVpdh

谢谢。

英文:

How found offset index a string in []rune using go?

I can do this work with string type.

if i := strings.Index(input[offset:], "}}"); i > 0 {print(i);}

but i need for runes.

i have a rune and want get offset index.

how can do this work with runes type in go?

example for more undrestand want need:

int offset=0//mean start from 0 (this is important for me)
string text="123456783}}56"
if i := strings.Index(text[offset:], "}}"); i > 0 {print(i);}

output of this example is : 9

but i want do this with []rune type(text variable)

may?

see my current code : https://play.golang.org/p/seImKzVpdh

tank you.

答案1

得分: 3

编辑#2: 你再次提到了你问题的一个新的“含义”:你想在[]rune中搜索一个string

答案:标准库中没有直接支持这个功能。但是可以通过两个for循环来实现:

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

编辑: 你更新了问题,表示你想在一个string中搜索rune

你可以通过简单的类型转换将[]rune转换为string

toSearchRunes := []rune{'}', '}'}
toSearch := string(toSearchRunes)

然后,你可以像在你的示例中那样使用strings.Index()

if i := strings.Index(text[offset:], toSearch); i > 0 {
    print(i)
}

Go Playground上尝试一下。

原始答案如下:


在Go中,string值以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也必须是一个字节位置,因为当像text[offset:]这样切片一个string时,索引被解释为字节索引。

如果你想获取一个rune的索引,可以使用strings.IndexRune()而不是strings.Index()

英文:

Edit #2: You again indicated a new type "meaning" of your question: you want to search a string in a []rune.

Answer: this is not supported directly in the standard library. But it's easy to implement it with 2 for loops:

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
}

Testing it:

value := []rune("123}456}}789")
result := search(value, "}}")
fmt.Println(result)

Output (try it on the Go Playground):

7

Edit: You updated the question indicating that you want to search runes in a string.

You may easily convert a []rune to a string using a simple type conversion:

toSearchRunes := []rune{'}', '}'}
toSearch := string(toSearchRunes)

And from there on, you can use strings.Index() as you did in your example:

if i := strings.Index(text[offset:], toSearch); i > 0 {
    print(i)
}

Try it on the Go Playground.

Original answer follows:


string values in Go are stored as UTF-8 encoded bytes. strings.Index() returns you the byte position if the given substring is found.

So basically what you want is to convert this byte-position to rune-position. The unicode/utf8 package contains utility functions for telling the rune-count or rune-length of a string: utf8.RuneCountInString().

So basically you just need to pass the substring to this function:

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]))
}

Output (try it on the Go Playground):

byte-pos: 9 rune-pos: 9
byte-pos: 6 rune-pos: 2

Note: offset must also be a byte position, because when slicing a string like text[offset:], the index is interpreted as byte-index.

If you want to get the index of a rune, use strings.IndexRune() instead of strings.Index().

huangapple
  • 本文由 发表于 2017年1月31日 19:26:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/41956391.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定