Question

How to Check Whether a String Contains a Substring in Go

gosubstring

Question

How can I check whether one string contains another string in Go?

For example, I want behavior similar to this:

someString.contains("something")

What is the correct Go approach for testing whether a string includes a substring?

Short Answer

By the end of this page, you will understand how to check whether a string contains a substring in Go using the standard library. You will also learn the required syntax, how it behaves with case sensitivity, how developers use it in real code, and what mistakes beginners often make.

Concept

In Go, strings do not have methods like contains() attached directly to them. Instead, Go puts many string-related operations in the standard library package strings.

To check whether one string appears inside another, you use:

strings.Contains(s, substr)

It returns a bool:

  • true if substr exists anywhere inside s
  • false if it does not

Example:

strings.Contains("hello world", "world") // true

This matters because substring checks are common in real programs:

  • validating user input
  • checking file paths or URLs
  • filtering logs
  • inspecting API responses
  • detecting keywords in text

Go's design prefers simple, explicit functions from packages over attaching many methods to built-in types. That is why you use strings.Contains instead of someString.contains(...).

Mental Model

Think of a string as a long line of text, and a substring as a smaller piece of paper with text written on it.

strings.Contains answers this question:

  • "Can I find this small piece of text somewhere inside the larger line of text?"

If the larger text is:

"golang is fun"

and the smaller text is:

"is"

then the answer is true because that sequence of characters appears inside the larger string.

It is like searching for a word inside a sentence.

Take Quiz

Syntax and Examples

Core syntax

strings.Contains(fullString, subString)

You must import the strings package:

import "strings"

Basic example

package main

import (
	"fmt"
	"strings"
)

func main() {
	text := "I am learning Go"

	fmt.Println(strings.Contains(text, "Go"))       // true
	fmt.Println(strings.Contains(text, "Python"))   // false
}

Explanation

  • text is the main string.
  • "Go" is searched inside text.
  • Since "Go" exists in "I am learning Go", the result is true.
  • "Python" does not exist there, so the result is false.

Example in an if statement

package main

import (
	"fmt"
	"strings"
)

func main() {
	email := "user@example.com"

	if strings.Contains(email, "@") {
		fmt.Println("Looks like an email address")
	} else {
		fmt.Println("Missing @ symbol")
	}
}

This is a common pattern when validating or inspecting text.

Case sensitivity example

package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println(strings.Contains("GoLang", "Go")) // true
	fmt.Println(strings.Contains("GoLang", "go")) // false
}

strings.Contains is case-sensitive.

Case-insensitive check

package main

import (
	"fmt"
	"strings"
)

func main() {
	text := "GoLang"
	sub := "go"

	result := strings.Contains(strings.ToLower(text), strings.ToLower(sub))
	fmt.Println(result) // true
}

A common approach is to convert both strings to the same case first.

Step by Step Execution

Consider this code:

package main

import (
	"fmt"
	"strings"
)

func main() {
	message := "backend-api-server"
	found := strings.Contains(message, "api")
	fmt.Println(found)
}

Step-by-step

1. Import packages

import (
	"fmt"
	"strings"
)
  • fmt is used to print output.
  • strings provides substring functions.

2. Create the main string

message := "backend-api-server"

The variable message now stores that full text.

3. Search for the substring

found := strings.Contains(message, "api")

Go checks whether the characters "api" appear in "backend-api-server".

They do appear, so:

found = true

4. Print the result

fmt.Println(found)

The output is:

true

Another trace

fmt.Println(strings.Contains("banana", "nan")) // true

Why?

  • Go scans the string "banana"
  • It finds the sequence "nan"
  • So the function returns true

Real World Use Cases

Input validation

Check whether a user entered required symbols or keywords.

strings.Contains(password, "#")
strings.Contains(email, "@")

URL and route checks

Detect whether a request path contains a certain section.

strings.Contains(path, "/admin")

Log filtering

Search log messages for error words.

strings.Contains(logLine, "ERROR")

File processing

Check whether a filename includes an extension or naming pattern.

strings.Contains(fileName, ".csv")

API response inspection

Quickly inspect text responses for expected markers.

strings.Contains(responseBody, "success")

Content moderation or keyword detection

Detect blocked words or target phrases inside submitted text.

strings.Contains(comment, bannedWord)
Take Quiz

Real Codebase Usage

In real Go projects, strings.Contains is often used as a small building block inside larger logic.

Guard clauses

Developers often reject invalid input early.

if !strings.Contains(email, "@") {
	return errors.New("invalid email address")
}

Filtering collections

Used when iterating through slices of strings.

for _, name := range names {
	if strings.Contains(name, "test") {
		fmt.Println(name)
	}
}

Case-normalized checks

Many codebases normalize strings before searching.

if strings.Contains(strings.ToLower(role), "admin") {
	fmt.Println("admin-related role")
}

Configuration and environment checks

Developers inspect environment values or config strings.

if strings.Contains(host, "localhost") {
	fmt.Println("running locally")
}

Error handling and diagnostics

Substring checks are sometimes used to classify text-based errors.

if err != nil && strings.Contains(err.Error(), "timeout") {
	fmt.Println("request timed out")
}

This pattern exists, though structured error handling is usually better when available.

Combined with other string helpers

It is common to use Contains together with:

  • strings.HasPrefix
  • strings.HasSuffix
  • strings.TrimSpace
  • strings.ToLower
  • strings.Split

These helpers often appear together in parsing and validation code.

Common Mistakes

1. Forgetting to import the strings package

Broken code:

package main

import "fmt"

func main() {
	fmt.Println(strings.Contains("hello", "he"))
}

Problem:

  • strings is not imported, so the code will not compile.

Fix:

import (
	"fmt"
	"strings"
)

2. Trying to call .contains() like other languages

Broken code:

someString.contains("something")

Problem:

  • Go strings do not have a contains method.

Fix:

strings.Contains(someString, "something")

3. Expecting case-insensitive behavior

Broken assumption:

strings.Contains("Hello", "hello") // false

Problem:

  • Contains is case-sensitive.

Fix:

strings.Contains(strings.ToLower("Hello"), strings.ToLower("hello")) // true

4. Using Contains when prefix or suffix checks are better

Sometimes you do not want to know whether text appears anywhere. You want to know whether it starts or ends with something.

Less precise:

strings.Contains(fileName, ".go")

Better if checking file extension:

strings.HasSuffix(fileName, ".go")

5. Confusing empty substring behavior

strings.Contains("hello", "") // true

This surprises some beginners. An empty string is considered to be contained in every string.

6. Searching formatted data too loosely

strings.Contains("id=12", "2") // true

This may be technically correct, but too broad for structured parsing. If the input has structure, parsing may be safer than substring matching.

Comparisons

ConceptWhat it checksExampleBest use
strings.Contains(s, sub)Whether sub appears anywhere in sstrings.Contains("golang", "la")General substring search
strings.HasPrefix(s, prefix)Whether s starts with prefixstrings.HasPrefix("/api/users", "/api")Route and path checks
strings.HasSuffix(s, suffix)Whether s ends with suffixstrings.HasSuffix("main.go", ".go")File extension checks
strings.Index(s, sub)Position of sub in s, or -1 if missingstrings.Index("golang", "la")When you need the location

Contains vs Index

Use Contains when you only care about true or false.

strings.Contains("golang", "go") // true

Use Index when you also need the position.

strings.Index("golang", "go") // 0

Contains vs regular expressions

  • Contains is simpler and clearer for plain text matching.
  • Regular expressions are better for patterns.

Example:

strings.Contains("user123", "123")

Use this for direct text checks.

If you need something like "contains one or more digits at the end," a regex may be more appropriate.

Take Quiz

Cheat Sheet

import "strings"

Check whether a string contains a substring

strings.Contains(s, sub)
  • Returns true or false
  • Case-sensitive
  • Works on plain strings

Examples

strings.Contains("hello world", "world") // true
strings.Contains("hello world", "Go")    // false
strings.Contains("GoLang", "go")         // false

Case-insensitive version

strings.Contains(strings.ToLower(s), strings.ToLower(sub))

Related helpers

strings.HasPrefix(s, prefix)
strings.HasSuffix(s, suffix)
strings.Index(s, sub)

Important edge case

strings.Contains("abc", "") // true

Common pattern

if strings.Contains(text, "error") {
	fmt.Println("found error text")
}

FAQ

How do I check if a string contains text in Go?

Use strings.Contains(mainString, subString) from the strings package.

Is strings.Contains case-sensitive in Go?

Yes. strings.Contains("Go", "go") returns false.

What package do I need for substring checks in Go?

You need the standard library package strings.

import "strings"

Can I use .contains() directly on a string in Go?

No. Go strings do not have a .contains() method. Use strings.Contains(...) instead.

How do I do a case-insensitive contains check in Go?

A common approach is to convert both values to the same case first:

strings.Contains(strings.ToLower(a), strings.ToLower(b))

What happens if the substring is empty?

strings.Contains(s, "") returns true.

Should I use Contains or HasSuffix for file extensions?

Use strings.HasSuffix when checking whether a filename ends with an extension like .go or .json. It is more precise than Contains.

Take Quiz

Mini Project

Description

Build a small Go program that filters a list of log messages and prints only the ones containing the word error. This demonstrates how substring checks are used in scripts, debugging tools, and backend utilities.

Goal

Create a Go program that scans several strings and prints the messages that contain a target substring.

Requirements

  • Import and use the strings package.
  • Store several log messages in a slice.
  • Check each log message for a target substring.
  • Print only the matching messages.
  • Make the match case-insensitive.
Take Quiz

Keep learning

Related questions

View more