T145
T145

Reputation: 1523

Go: Retrieve a string from between two characters or other strings

Let's say for example that I have one string, like this:

<h1>Hello World!</h1>

What Go code would be able to extract Hello World! from that string? I'm still relatively new to Go. Any help is greatly appreciated!

Upvotes: 13

Views: 37969

Answers (9)

kwatson
kwatson

Reputation: 29

How about:

func SplitBetween(str, bef, aft string) string {
    sa := strings.SplitN(str, bef, 2)
    if len(sa) == 1 {
        return ""
    }
    sa = strings.SplitN(sa[1], aft, 2)
    if len(sa) == 1 {
        return ""
    }
    return sa[0]
}

Returns empty string if split is not found.

Upvotes: 1

dganesh2002
dganesh2002

Reputation: 2230

Here is my answer using regex. Not sure why no one suggested this safest approach

package main

import (
    "fmt"
        "regexp"
)

func main() {
    content := "<h1>Hello World!</h1>"
    re := regexp.MustCompile(`<h1>(.*)</h1>`)
    match := re.FindStringSubmatch(content)
    if len(match) > 1 {
        fmt.Println("match found -", match[1])
    } else {
        fmt.Println("match not found")
    }
    
}

Playground - https://play.golang.org/p/Yc61x1cbZOJ

Upvotes: 6

Jan Kardaš
Jan Kardaš

Reputation: 333

If the string looks like whatever;START;extract;END;whatever you can use this which will get the string in between:

// GetStringInBetween Returns empty string if no start string found
func GetStringInBetween(str string, start string, end string) (result string) {
    s := strings.Index(str, start)
    if s == -1 {
        return
    }
    s += len(start)
    e := strings.Index(str[s:], end)
    if e == -1 {
        return
    }
    e += s + e - 1
    return str[s:e]
}

What happens here is it will find first index of START, adds length of START string and returns all that exists from there until first index of END.

Upvotes: 20

ttrasn
ttrasn

Reputation: 4851

I improved the Jan Kardaš`s answer. now you can find string with more than 1 character at the start and end.

func GetStringInBetweenTwoString(str string, startS string, endS string) (result string,found bool) {
    s := strings.Index(str, startS)
    if s == -1 {
        return result,false
    }
    newS := str[s+len(startS):]
    e := strings.Index(newS, endS)
    if e == -1 {
        return result,false
    }
    result = newS[:e]
    return result,true
}

Upvotes: 7

gondo
gondo

Reputation: 1128

func Split(str, before, after string) string {
    a := strings.SplitAfterN(str, before, 2)
    b := strings.SplitAfterN(a[len(a)-1], after, 2)
    if 1 == len(b) {
        return b[0]
    }
    return b[0][0:len(b[0])-len(after)]
}

the first call of SplitAfterN will split the original string into array of 2 parts divided by the first found after string, or it will produce array containing 1 part equal to the original string.

second call of SplitAfterN uses a[len(a)-1] as input, as it is "the last item of array a". so either string after after or the original string str. the input will be split into array of 2 parts divided by the first found before string, or it will produce array containing 1 part equal to the input.

if after was not found than we can simply return b[0] as it is equal to a[len(a)-1]

if after is found, it will be included at the end of b[0] string, therefore you have to trim it via b[0][0:len(b[0])-len(after)]

all strings are case sensitive

Upvotes: -1

Andre Romano
Andre Romano

Reputation: 1012

func findInString(str, start, end string) ([]byte, error) {
    var match []byte
    index := strings.Index(str, start)

    if index == -1 {
        return match, errors.New("Not found")
    }

    index += len(start)

    for {
        char := str[index]

        if strings.HasPrefix(str[index:index+len(match)], end) {
            break
        }

        match = append(match, char)
        index++
    }

    return match, nil
}

Upvotes: 1

jmaloney
jmaloney

Reputation: 12320

In the strings pkg you can use the Replacer to great affect.

r := strings.NewReplacer("<h1>", "", "</h1>", "")
fmt.Println(r.Replace("<h1>Hello World!</h1>"))

Go play!

Upvotes: 1

DiBa
DiBa

Reputation: 322

There are lots of ways to split strings in all programming languages.

Since I don't know what you are especially asking for I provide a sample way to get the output you want from your sample.

package main

import "strings"
import "fmt"

func main() {
    initial := "<h1>Hello World!</h1>"

    out := strings.TrimLeft(strings.TrimRight(initial,"</h1>"),"<h1>")
    fmt.Println(out)
}

In the above code you trim <h1> from the left of the string and </h1> from the right.

As I said there are hundreds of ways to split specific strings and this is only a sample to get you started.

Hope it helps, Good luck with Golang :)

DB

Upvotes: 15

miltonb
miltonb

Reputation: 7385

Read up on the strings package. Have a look into the SplitAfter function which can do something like this:

var sample = "[this][is my][string]"
t := strings.SplitAfter(sample, "[")

That should produce a slice something like: "[", "this][", "is my][", "string]". Using further functions for Trimming you should get your solution. Best of luck.

Upvotes: 1

Related Questions