Fluffy
Fluffy

Reputation: 28362

How to find a substring skipping N chars

How do I get the index of a substring in a string skipping starting with a certain position/with a certain offset, e.g.:

package main

import (
    "fmt"
    "strings"
)

func main() {
    string := "something.value=something=end"
    index1 := strings.Index(string, "value=")
    fmt.Println(index1) // prints 10
    // index2 = ... How do I get the position of the second =, 25?
}

Similar offset in PHP int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

Upvotes: 0

Views: 1176

Answers (2)

DevBazilio
DevBazilio

Reputation: 1

taking a slice of string with utf-8 characters may produce corrupted strings as you need to convert it to runes

[]rune(videoHtml)[0:index]

Upvotes: -1

icza
icza

Reputation: 417572

The strings package does not provide you such function, but in practice it's rarely needed. Often the strings.Split() function is used to easily split strings into tokens / parts.

But if you do need it: you can simply slice a string, which is efficient (no copy is made, the result shares memory with the original string value).

So effectively the function you're looking for would look like this:

func Index(s, substr string, offset int) int {
    if len(s) < offset {
        return -1
    }
    if idx := strings.Index(s[offset:], substr); idx >= 0 {
        return offset + idx
    }
    return -1
}

Example using it:

s := "something.value=something=end"
index1 := strings.Index(s, "value=")
fmt.Println(index1) // prints 10

index2 := Index(s, "=", index1+len("value="))
fmt.Println(index2) // prints 25

Output (try it on the Go Playground):

10
25

Note that when slicing a string, and the offset you have to pass to our Index() function is the byte index, not the rune (character) index. They are equal as long as you have characters with less than 128 codepoints, but beyond that the byte index will be greater than the rune index because those codepoints map to multiple bytes in UTF-8 encoding (which is how Go stores strings in memory). strings.Index() returns you the byte index, and len(s) also returns you the byte-length, so the example will work with all strings properly.

Your original task using strings.Split() could look like this:

s := "something.value=something=end"
parts := strings.Split(s, "=")
fmt.Println(parts)

Which outputs (try it on the Go Playground):

[something.value something end]

The value you want to "parse" out is in parts[1].

Upvotes: 3

Related Questions