How does regexp (RE2) differ from PCRE engines? Why doesn't Go support backreferences, and what are the performance guarantees?
Go's regexp uses RE2 syntax and automata-based matching (a Thompson NFA, a one-pass matcher and a bounded backtracker). It guarantees matching in O(m·n) time, linear in the input length for a given pattern, so catastrophic backtracking (ReDoS) cannot happen. The cost is losing features that require backtracking: backreferences (\1) and lookahead/lookbehind. Matching with backreferences is NP-hard, so no linear-time guarantee can include them. That is why patterns taken from user input are safe to run in Go.
evil := regexp.MustCompile(`^(a+)+
How does regexp (RE2) differ from PCRE engines? Why doesn't Go… | Go Interview Question
)
fmt.Println(evil.MatchString(strings.Repeat("a", 50) + "b")) // false, instantly (PCRE: exponential)
_, err := regexp.Compile(`(\w)\1`)
fmt.Println(err) // error parsing regexp: invalid escape sequence: `\1`
// What does this print? Leftmost-first (Perl) vs leftmost-longest (POSIX)
fmt.Println(regexp.MustCompile(`a|ab`).FindString("ab")) // a
fmt.Println(regexp.MustCompilePOSIX(`a|ab`).FindString("ab")) // ab
var slugRe = regexp.MustCompile(`^[a-z0-9]+(?:-[a-z0-9]+)*
How does regexp (RE2) differ from PCRE engines? Why doesn't Go… | Go Interview Question
) // compile once at package level
Performance notes: the constant factor is often higher than PCRE or JIT engines for simple patterns. Compile patterns once, never inside a loop or a handler. For simple checks, use strings.Contains, HasPrefix or Cut. A *Regexp is safe for concurrent use. If you need backreferences, do a second pass in code, or use a third-party backtracking library and set timeouts.
More on More Standard Library Essentials
- Q537How do you prevent SQL injection with database/sql? Why can't placeholders be used for table names or ORDER BY columns?
- Q538Why should you compare secrets with crypto/subtle.ConstantTimeCompare instead of ==? How do you hash passwords in Go?
- Q540How do you run external commands safely with os/exec? Explain CommandContext, capturing stdout/stderr, exit codes, and why shell injection is not the default risk.
- Q541How do you build a TCP server with net.Listen? Handle per-connection goroutines, read/write deadlines, and graceful shutdown of the listener.
- Q542Explain io/fs and fs.FS. How do you walk a directory with filepath.WalkDir and test file-system code with testing/fstest.MapFS?
- Q543What is os.Root (Go 1.24), and how does it prevent path-traversal attacks compared to filepath.Join plus filepath.Clean?