0

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?

1
  • I'd scan from the start & end until you hit an asterisk - then you know the sub-string indices. So a simple for-loop would be way more efficient to do this than any strings or rexexp function. Commented Aug 22, 2022 at 21:59

5 Answers 5

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

Split on any number of asterisks:

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

See live demo.

Comments

0

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.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.