Regular expressions
| MustCompile once | |
| Match strings | |
| Find submatches | |
| Replace all |
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