15

I want to extract a string till a character is found. For example:

message := "Rob: Hello everyone!"
user := strings.Trim(message,

I want to be able to store "Rob" (read till ':' is found).

3 Answers 3

35

You may use strings.IndexByte() or strings.IndexRune() to get the position (byte-index) of the colon ':', then simply slice the string value:

message := "Rob: Hello everyone!"
user := message[:strings.IndexByte(message, ':')]
fmt.Println(user)

Output (try it on the Go Playground):

Rob

If you're not sure the colon is in the string, you have to check the index before proceeding to slice the string, else you get a runtime panic. This is how you can do it:

message := "Rob: Hello everyone!"
if idx := strings.IndexByte(message, ':'); idx >= 0 {
    user := message[:idx]
    fmt.Println(user)
} else {
    fmt.Println("Invalid string")
}

Output is the same.

Changing the message to be invalid:

message := "Rob Hello everyone!"

Output this time is (try it on the Go Playground):

Invalid string

Another handy solution is to use strings.Split():

message := "Rob: Hello everyone!"

parts := strings.Split(message, ":")
fmt.Printf("%q\n", parts)

if len(parts) > 1 {
    fmt.Println("User:", parts[0])
}

Output (try it on the Go Playground):

["Rob" " Hello everyone!"]
User: Rob

Should there be no colon in the input string, strings.Split() returns a slice of strings containing a single string value being the input (the code above does not print anything in that case as length will be 1).

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

1 Comment

If message is untrusted user data, you most likely don't want to use strings.Split just to get the part (if any) before :, because doing this may require many allocations in the face of a message composed of maliciously many :. See github.com/rs/cors/issues/170
6

strings.Index or strings.IndexRune, depending on whether you want to use unicode as the separator, will give you the index of the sought character.

Alternatively, you can use strings.Split and just grab the first string returned.

Example: user := strings.Split(message, ":")[0]

https://play.golang.org/p/I1P1Liz1F6

Notably, this will not panic if the separator character is not in the original string, but the user variable will be set to the entirety of the original string instead.

Comments

6

The other answers don't mention this, but Go 1.18 saw the addition of a very convenient strings.Cut function, which obviates the need to deal with indices:

message := "Rob: Hello everyone!"
before, after, found := strings.Cut(message, ":")
fmt.Printf("%q %q %t\n", before, after, found) // "Rob" " Hello everyone!" true

message = "Rob Hello everyone!"
before, after, found = strings.Cut(message, ":")
fmt.Printf("%q %q %t\n", before, after, found) // "Rob Hello everyone!" "" false

(Playground)

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.