String Functions in Go – Part 1

  • Home
  • /
  • String Functions in Go – Part 1

String Functions in Go – Part 1

Programming 15 Feb 2018

Go is a powerful programming language in the best tradition of C. However, Go tries to eliminate some of C’s shortcomings. If you programmed Go, you probably like the brevity and safety. Yes, safety and comfort come at a cost of performance but Go is still insanely fast language.

One of the areas where Go is dramatically better than C is working with strings. The strings package is Go’s powerhouse for working with strings. The package contains many string functions and makes string manipulation a breathe. Though, there are some caveats and it’s very important to know what the strings package delivers.

The first thing that you need to remember is that some of Go’s string functions are CaSe SeNsItIvE, while others are not. I will clearly indicate this along with each function below.

When working with strings, we face two group of tasks. The first group is querying and checking (e.g. if strings are equal, if one string contains another, etc). The second group is actual manipulation of strings (e.g. removing characters from a string, replacing something in a string, etc). In this part I will focus on the first group. The second group will be addressed in a separate post. Let’s get started.

How to Compare Strings

One of the most common tasks when working with strings is string comparison. In Go you can do this either by using the strings.Compare function or by using the built-in operators: ==, <, >. String comparison is CaSe SeNsItIvE!

Function syntax:

func Compare(a, b string) int

Let’s have a look at an example:

package main

import (
    "fmt"
    "strings"
)

func main() {

    fmt.Println(strings.Compare("MAGIC", "magic")) // MAGIC is less than magic - CaSe SeNsItIvE
    fmt.Println(strings.Compare("MAGIC", "MAGIC")) // MAGIC and MAGIC are equal

    fmt.Println(strings.Compare("", ""))  // empty strings are equal
    fmt.Println(strings.Compare("", " ")) // empty string is less than any other string

    fmt.Println("MAGIC" == "magic") // prints false as the strings are not equal
    fmt.Println("MAGIC" < "magic")  // prints true as MAGIC is less then magic

}

Do you want to test how well you grasped string comparison? Without using Go, guess what the following statement would print:

fmt.Println(("MAGIC" < "magic") == (strings.Compare("MAGIC", "magic") == -1))

How to Check if One String Contains Another

Another common task is checking if one string contains another string. For this task, we can use the strings.Contains function. You feed in two strings and get a boolean result. This function is also CaSe SeNsItIvE! Another thing to note is that empty string always contains empty string.

Function syntax:

func Contains(s, substr string) bool

Let’s have a look at an example:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Contains("It's a kind of magic", "magic")) // prints true
    fmt.Println(strings.Contains("It's a kind of magic", "MAGIC")) // prints false - CaSe SeNsItIvE
    fmt.Println(strings.Contains("", ""))                          // prints true - empty string contains empty string
}

How to Check if Characters are Present in a String

Sometimes you need to check if certain characters are present in a given string. You could use several strings.Contains function calls when you have more than two characters but there’s a better way in Go – the strings.ContainsAny function.

Function syntax:

func ContainsAny(s, chars string) bool

Let’s have a look at the example:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.ContainsAny("magic", "m"))   // prints true - m is in magic
    fmt.Println(strings.ContainsAny("magic", "M"))   // prints false - M is not in magic
    fmt.Println(strings.ContainsAny("magic", "m a")) // prints true - both m and a are in magic
    fmt.Println(strings.ContainsAny("magic", "m z")) // prints true - z is not in magic, but m is.
    fmt.Println(strings.ContainsAny("magic", "p z")) // prints false - neither p nor z are present in magic
}

How to Find a Position of a Sub-string in another String

Use strings.Index function to find a position of a sub-string in a string. The function returns -1 if the string does not contain sub-string or a value of zero or more. Zero means the beginning of the string. Like the previous functions, strings.Index function is also CaSe SeNsItIvE!

Function syntax:

func Index(s, substr string) int

Let’s look at the example:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Index("magic", "gi")) // prints 2 - gi occurs at index 2
    fmt.Println(strings.Index("magic", "GI")) // prints -1 - GI because Index function is CaSe SeNsItIvE
    fmt.Println(strings.Index("magic", "me")) // prints -1 - me does not occur in magic

}

How to Find Positions of Characters in a String

Like the strings.Contains function has a strings.ContainAny cousin, so does strings.Index has strings.IndexAny function. Though, it’s a little bit more subtle. The example below will show them. This function is also CaSe SeNsItIvE!

Function syntax:

func IndexAny(s, chars string) int

Let’s look at the example:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.IndexAny("magic", "a c")) // prints 1 - a's position is returned
    fmt.Println(strings.IndexAny("magic", "j c")) // prints 4 - c's position is returned
    fmt.Println(strings.IndexAny("magic", "A C")) // prints -1 - as neither A nor C is present in magic

}

One thing to keep in mind is that strings.Index and strings.IndexAny functions return the index of the first occurrence of a sub-string or chars. It is also possible to find the last occurance of a sub-string or char by using the strings.LastIndex and strings.LastIndexAny functions.

Funtion syntax:

func LastIndex(s, substr string) int
func LastIndexAny(s, chars string) int

Let’s look at a combined example of Index, IndexAny, LastIndex and LastIndexAny functions.

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Index("magic tricks", "ic"))     // prints 3 - ic's first position
    fmt.Println(strings.LastIndex("magic tricks", "ic")) // prints 8 - ic's last position

    fmt.Println(strings.IndexAny("magic tricks", "a c"))     // prints 1 - a's first position
    fmt.Println(strings.LastIndexAny("magic tricks", "a c")) // prints 9 - c's last position
}

How to Find Out if a String Begins or Ends with a Certain Sub-string

Go’s strings package contains two more useful functions, strings.HasPrefix and strings.HasSuffix. Use these functions to test if a string has certain beginning or ending. Like the other string functions, these two are also CaSe SeNsItIvE!

Function syntax:

func HasPrefix(s, prefix string) bool
func HasSuffix(s, suffix string) bool

Let’s look at the examples:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.HasPrefix("magic", "ma")) // prints true - magic starts with ma
    fmt.Println(strings.HasPrefix("magic", "MA")) // prints false - magic does not starts with MA
    fmt.Println(strings.HasSuffix("magic", "ic")) // prints true - magic ends with ic
    fmt.Println(strings.HasSuffix("magic", "IC")) // prints false - magic does not ends with IC
}

I hope you found the above overview and examples useful. There are some other string functions in the strings package, but they are used less frequently. At least, I have described all high-frequency string functions. In the next post I will write how to do some interesting things with our strings. Stay tuned and happy programming!