Regular expressions

MustCompile once

The regexp package matches text against patterns. A pattern starts as a string, but matching runs faster when Go compiles it once into a Regexp value and reuses that value.

MustCompile builds the Regexp and stops the program when the pattern is broken. That behavior is a good fit for constant patterns, because a broken constant should fail loudly during development rather than hide in production.

The program below compiles one pattern and tests four strings against it. Backquotes mark a raw string, so backslashes in the pattern need no doubling.

package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`^go[0-9]+$`) words := []string{"go1", "go21", "golang", "go"} for _, w := range words { fmt.Println(w, re.MatchString(w)) } }

go1 true

go21 true

golang false

go false

Match strings

MatchString answers a yes or no question about one string. It is the simplest check in the package and a good default for validation.

The package also offers Match, which compiles the pattern on every call and reports a compile error. Prefer a compiled Regexp when the check runs more than once, and keep Match for rare one off checks.

package main import ( "fmt" "regexp" ) func main() { first, err := regexp.Match(`[0-9]+`, []byte("abc123")) if err != nil { fmt.Println(err) return } fmt.Println(first) re := regexp.MustCompile(`[0-9]+`) fmt.Println(re.MatchString("abc")) fmt.Println(re.MatchString("abc123")) }

true

false

true

Find submatches

Matching tells whether text fits. Finding tells which part fits. FindString returns the matched part, while FindAllString collects every match with a limit on the count.

Parentheses create groups, and FindStringSubmatch returns the full match followed by one entry per group. Groups count from one, so the year in the example sits at index one.

package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`) line := "date: 2026-10-06" found := re.FindString(line) fmt.Println(found) parts := re.FindStringSubmatch(line) fmt.Println(parts[1], parts[2], parts[3]) }

2026-10-06

2026 10 06

Replace all

ReplaceAllString swaps every match with new text. The replacement may reference groups with dollar names such as $1, which makes reformatting dates and codes a one line task.

Remember that the first argument is a pattern, not plain text. Dots, plus signs, and brackets keep their special meaning, so quote them with a backslash when matching them literally.

package main import ( "fmt" "regexp" ) func main() { re := regexp.MustCompile(`\s+`) fmt.Println(re.ReplaceAllString("go is fast", " ")) dated := regexp.MustCompile(`(\d{2})\.(\d{2})\.(\d{4})`) fmt.Println(dated.ReplaceAllString("06.10.2026", "$3-$2-$1")) }

go is fast

2026-10-06

Next: Sorting

Article author: Arthur Isaev