Home > other >  Splitting string in 2 parts by removing substring in golang
Splitting string in 2 parts by removing substring in golang

Time:08-24

I'm trying to parse strings that look something like this:

abc***********xyz

into a slice (or 2 variables) of "abc" and "xyz", removing all the asterisks.

The number of * can be variable and so can the letters on each side, so it's not necessarily a fixed length. I'm wondering if go has a nice way of doing this with the strings package?

CodePudding user response:

Use strings.FieldsFunc where * is a field separator.

s := "abc***********xyz"
z := strings.FieldsFunc(s, func(r rune) bool { return r == '*' })
fmt.Println(len(z), z)  // prints 2 [abc xyz]

Live Example.

CodePudding user response:

Split on any number of asterisks:

words := regexp.MustCompile(`\* `).Split(str, -1)

See live demo.

CodePudding user response:

For best performance, write a for loop:

func SplitAsteriks(s string) []string {
    var (
        in     bool     // true if inside a token
        tokens []string // collect function result here
        i      int
    )
    for j, r := range s {
        if r == '*' {
            if in {
                // transition from token to separator
                tokens = append(tokens, s[i:j])
                in = false
            }
        } else {
            if !in {
                // transition from one or more separators to token
                i = j
                in = true
            }
        }
    }
    if in {
        tokens = append(tokens, s[i:])
    }
    return tokens
}

Playground.

CodePudding user response:

if performance is an issue, you can use this func:

func SplitAsteriks(s string) (result []string) {
    if len(s) == 0 {
        return
    }

    i1, i2 := 0, 0

    for i := 0; i < len(s); i   {
        if s[i] == '*' && i1 == 0 {
            i1 = i
        }
        if s[len(s)-i-1] == '*' && i2 == 0 {
            i2 = len(s) - i
        }
        if i1 > 0 && i2 > 0 {
            result = append(result, s[:i1], s[i2:])
            return
        }
    }

    result = append(result, s)
    return
}

playground

CodePudding user response:

Use this code given that the string is specified to have two parts:

s := "abc***********xyz"
p := s[:strings.IndexByte(s, '*')]
q := s[strings.LastIndexByte(s, '*') 1:]
fmt.Println(p, q) // prints abc xyz
  • Related