Regex in Go
Go's regexp package implements RE2 syntax — a guaranteed-linear-time regex engine. This means no backtracking, which makes Go regex safe from catastrophic backtracking (ReDoS) but also means some features like lookaheads and backreferences are not supported.
Code Examples
Basic matching
package main
import (
"fmt"
"regexp"
)
func main() {
matched, _ := regexp.MatchString(`\d{3}-\d{4}`, "Call 555-1234")
fmt.Println(matched) // true
// Compile for reuse (preferred)
re := regexp.MustCompile(`[a-z]+@[a-z]+\.[a-z]+`)
fmt.Println(re.MatchString("user@example.com")) // true
}regexp.MatchString() is a one-off check. For repeated use, compile with regexp.MustCompile() (panics on invalid pattern) or regexp.Compile() (returns an error).
Find and extract matches
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`(\d+)\.(\d+)`)
text := "Versions: 1.21, 2.0, 3.14"
// FindString: first match
fmt.Println(re.FindString(text)) // "1.21"
// FindAllString: all matches
fmt.Println(re.FindAllString(text, -1))
// ["1.21", "2.0", "3.14"]
// FindStringSubmatch: match + groups
m := re.FindStringSubmatch(text)
fmt.Println(m) // ["1.21", "1", "21"]
}Find methods come in variants: FindString (first match), FindAllString (all matches), FindStringSubmatch (match with groups). The -1 argument means find all.
Named capture groups
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(
`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`,
)
match := re.FindStringSubmatch("2026-03-08")
names := re.SubexpNames()
result := make(map[string]string)
for i, name := range names {
if i > 0 && name != "" {
result[name] = match[i]
}
}
fmt.Println(result)
// map[day:08 month:03 year:2026]
}Go uses (?P<name>...) syntax for named groups (same as Python). SubexpNames() returns group names by index. There's no direct map accessor — you build it manually.
Replace with ReplaceAllString
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
re := regexp.MustCompile(`(\w+)\s(\w+)`)
// Simple replacement with group references
result := re.ReplaceAllString("John Smith", "$2, $1")
fmt.Println(result) // "Smith, John"
// Replace with a function
upper := re.ReplaceAllStringFunc("hello world", strings.ToUpper)
fmt.Println(upper) // "HELLO WORLD"
}ReplaceAllString() supports $1, $2 group references. ReplaceAllStringFunc() accepts a function for dynamic replacements — but the function only receives the full match, not individual groups.
Split with regex
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\s*[,;]\s*`)
parts := re.Split("one, two; three, four", -1)
fmt.Println(parts) // ["one", "two", "three", "four"]
}regexp.Split() works like strings.Split() but accepts a regex pattern. Pass -1 to get all substrings.
Note
Go uses the RE2 engine, which guarantees linear-time matching by disallowing backreferences and lookaround assertions. This makes Go regex immune to ReDoS attacks but means you cannot use lookaheads (?=), lookbehinds (?<=), or backreferences (\1) in patterns. Use raw string literals (backticks) to avoid backslash escaping issues.
Regex in Other Languages
Frequently Asked Questions
Why doesn't Go support lookaheads and lookbehinds?
Go uses the RE2 regex engine, which guarantees linear-time matching by design. Lookaheads and lookbehinds can cause exponential backtracking in worst-case scenarios, so RE2 excludes them. This is a deliberate trade-off: you lose some expressiveness but gain predictable performance and immunity to ReDoS attacks.
What is the difference between MustCompile() and Compile()?
regexp.Compile() returns (*Regexp, error) — use it when the pattern might be invalid (e.g., user input). regexp.MustCompile() panics if the pattern is invalid — use it for hard-coded patterns where a compile error would be a programmer bug.
How do I do case-insensitive matching in Go?
Add the (?i) flag at the start of your pattern: regexp.MustCompile(`(?i)hello`). Go supports inline flags: (?i) case-insensitive, (?m) multiline, (?s) dotall, (?U) ungreedy. There are no separate flag arguments like in Python or Java.
Can I use backreferences in Go regex?
No. Go's RE2 engine does not support backreferences (\1, \2, etc.) because they can cause exponential-time matching. If you need backreferences, you'll need to match the groups separately and compare them in Go code, or use a different regex library like github.com/dlclark/regexp2 which uses a .NET-compatible engine.
Want to test a Go regex pattern? Our regex tester runs JavaScript's native RegExp engine in your browser — paste your pattern and see matches in real time.
← Open the Regex Tester