Advertisement

RE2 vs PCRE — The Differences That Break Your Regex (and the Exact Fixes)

Your pattern works in JavaScript, Python and your IDE — then fails silently in Google Analytics 4, Go, Rust or BigQuery. The reason is almost always the engine: those systems run RE2, which rejects entire families of PCRE syntax. This page maps every difference and gives you the replacement pattern for each.

TL;DR: RE2 supports character classes, groups, alternation, anchors, \b, Unicode classes and non-greedy quantifiers — but no lookahead, no lookbehind, no backreferences, no atomic groups, no possessive quantifiers, no recursion. Every one of those has a recipe below.

Which engines use RE2, which use PCRE

Engine familyMembersAssertions?
RE2 (linear-time, no backtracking)Google Analytics 4, Go regexp, Rust regex crate, BigQuery REGEXP_*, Google Sheets, CassandraNo
PCRE / backtrackingPerl, PHP, Python re, JavaScript, Java, Ruby, .NETYes

JavaScript deserves a note: the browser's RegExp is PCRE-like — it has lookahead/lookbehind and backreferences, but it is not identical to PCRE either (no \K, no conditionals). It behaves like PCRE for everything this page covers.

What RE2 does not support — and what to use instead

PCRE constructRE2 replacement
Lookahead foo(?=bar) Match the full text: foobar, or capture the part you need: (foo)bar → use group 1 Try in tester →
Negative lookahead (?!admin) Negated character class for one position ([^x]), or split into an include filter plus an exclude filter in your tool (e.g. GA4) Try in tester →
Lookbehind (?<=/)(\w+) Include the prefix in the match: /(\w+), then use the capture group Try in tester →
Backreference (foo|bar)\1 Expand fixed alternatives — foofoo|barbar; dynamic equality checks belong in application code Try in tester →
Atomic group (?>\d+) Plain group (\d+) — RE2 never backtracks exponentially, so atomicity is pointless there Try in tester →
Possessive a++, \d*+ Normal quantifier a+, \d* — possessives exist only to stop backtracking, which RE2 does not do Try in tester →
Conditional (?(1)a|b) Write both branches as an explicit alternation, or handle in code
Recursion (?R), subroutine ( ?1 ) Not reproducible in regex — parse with a real parser or iterate in code
\K (reset match) Adjust the pattern boundary, then use a capture group for the interesting part

What RE2 fully supports (the good news)

Most day-to-day regex needs nothing from the unsupported list:

Why RE2 exists: catastrophic backtracking

PCRE engines backtrack: on adversarial input such as ^(a+)+$ matched against a long run of a that ends in X, the number of paths explodes exponentially and the CPU pins at 100% — the classic ReDoS (Regular Expression Denial of Service) attack. RE2's automaton-based matcher evaluates every position once, so that same pattern is harmless there. This is exactly why Google runs RE2 on untrusted input — GA4 filter definitions, BigQuery queries — and why the trade-off of losing lookahead was worth it for them.

(We deliberately do not link that pattern to the tester above — one click in a backtracking engine can freeze a browser tab. That freeze is the difference between the two engines.)

Testing for RE2 compatibility? Start here
Write your pattern in the tester, then check it against this page's unsupported list before shipping it to GA4, Go, Rust or BigQuery.
Open the regex tester →

FAQ

Does RE2 support lookahead or lookbehind?

No. Assertions need backtracking or unbounded memory; RE2's linear-time guarantee rules them out. Use character classes, alternation, capture groups, or a second filter.

Is Go's regexp RE2?

Yes — Go's regexp package implements RE2 syntax (no lookahead, no backreferences). Same for Rust's regex crate and BigQuery's REGEXP_CONTAINS / REGEXP_EXTRACT.

Why does RE2 not support backreferences?

Backreferences make matching NP-complete in the general case. RE2 trades them for a hard O(input × pattern) time bound. Expand fixed alternatives ((foo|bar)\1 → foofoo|barbar) or compare strings in code.

Is RE2 always faster than PCRE?

No — for simple patterns on friendly input, backtracking engines can be faster. RE2 wins on worst-case behavior: no ReDoS, no pathological slowdowns, predictable latency on large inputs.

GA4 is your RE2 target? See the GA4 regex cheat sheet, the page path regex guide and the event filter regex guide.