Finding ·
We ran sixty regexes from Google Sheets tutorials. All sixty work.
The article I set out to write said that the internet is full of broken Google Sheets regular
expressions. Lookahead everywhere. Backreferences copied out of JavaScript. \p{L} from somebody’s
Python. A cell would reject all of it, and nobody had ever checked.
So we checked. Sixty patterns, copied character for character out of twenty-nine published pages. Each quotation was then re-fetched from its source page by a second pass, because a model that knows regular expressions will quietly repair a broken one on the way past, and a claim about what somebody else published has to survive being wrong.
Every one of the sixty was written into a real Google Sheet.
All sixty work. Not one used lookahead. Not one used lookbehind. No backreferences inside a
pattern, no \p{L}, no possessive quantifiers. Every REGEXREPLACE used $1 in its replacement,
which is the form Sheets wants, and none used \1, which is the form that silently produces the
literal digit.
The hypothesis was wrong. The advice is sound.
What we actually ran
Every pattern went into REGEXMATCH against one fixed sample string, whatever function its author
had used it with. That is not a mistake. It is the only question with a single answer.
REGEXMATCH returns TRUE or FALSE for any pattern Sheets can parse, and #REF! for any pattern
it cannot, regardless of the text. Asking whether each pattern found what its author wanted would
have required guessing at their data. Asking whether Sheets can read it at all requires nothing.
Sixty patterns. Zero #REF!.
The advice is fine. The delivery is not.
Here is a formula from a page teaching REGEXMATCH, reproduced exactly as it is printed:
=REGEXMATCH(A1, “^d{2}/d{2}/d{4}$”)
Two things have happened to it, and both are invisible.
The quotation marks are “ and ”. Typographic quotes. They are different characters from ".
Copy that line into a cell and Sheets does not reach the regular expression at all:
=REGEXMATCH(“abc”,“b”) → #ERROR! Formula parse error.
And the backslashes are gone. \d{2} has become d{2}. Not a typo by the author — every single one
of the thirteen regex formulas on that page contains a curly quote, and not one of them contains a
backslash. Something between the writer and the page ate them.
So a reader who notices the quotes, retypes them, and pastes the rest gets this:
=REGEXMATCH("01/02/2026","^d{2}/d{2}/d{4}$") → FALSE
=REGEXMATCH("01/02/2026","^\d{2}/\d{2}/\d{4}$") → TRUE
A valid date, and the published pattern says no. Not #REF!. Not an error. FALSE — which in a
spreadsheet means this row does not match, and so the reader goes looking at their dates.
The one that should worry you
The same page publishes an email validator. Here it is as printed, and then as its author must have written it:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
One backslash. In the published version, \. has become ., which in a regular expression means
any character at all.
It still parses. It still returns TRUE for real addresses. And:
=REGEXMATCH("user@domainXcom", <as published>) → TRUE
=REGEXMATCH("user@domainXcom", <as written>) → FALSE
user@domainXcom passes validation. There is no dot in that domain. The pattern is checking that
something sits between the domain and the suffix, and an X is something.
This is a validator that has been letting bad addresses through, in whatever spreadsheets copied it, with no error, no warning, and no way for the person who trusted it to find out.
Four ways a copied formula fails
We ran all of them. Only one tells you anything true.
| What went wrong | What the cell says |
|---|---|
| Typographic quotes | #ERROR! — “Formula parse error” |
| A construct Sheets does not support | #REF! |
| A valid pattern with nothing to match | #N/A |
| A backslash lost in transit | nothing. Just the wrong answer. |
#ERROR! is the only honest one. It names a parse failure, and there was a parse failure.
#REF! is the error a spreadsheet gives when a formula points at a cell that no longer exists. It is
what you get after deleting a column. It is also what Sheets shows when your regular expression is
unsupported, which sends people hunting through their references for twenty minutes.
We confirmed that two ways: the cell prints #REF!, and ERROR.TYPE()
returns 4.
And the last row is the one that should keep you up. A pattern that lost a backslash produces a
value. TRUE. FALSE. A column of names replaced by a column of numbers. There is no signal at all.
Nobody told him about RE2
In a comment on a tutorial, dated July 2022, a reader wrote:
I have an email address in C2 and want to obscure it with asterisks. The pattern I found is
/(?!^).(?=[^@]+@)/… Not working. What am I missing?
Nothing. He was missing nothing.
He had found a JavaScript regular expression — slash delimiters and all — and Google Sheets does not run JavaScript’s regex engine. It runs RE2, which has no lookahead, because lookahead is what lets a pattern take exponential time on hostile input and RE2 exists to make that impossible. His pattern uses two of them.
=REGEXREPLACE("bob@acme.com","/(?!^).(?=[^@]+@)/","*") → #REF!
=REGEXREPLACE("bob@acme.com","(?!^).(?=[^@]+@)","*") → #REF!
Removing the slashes does not help. The lookaheads are the problem. And the cell told him it was a broken reference.
Here is what he wanted, written for the engine he was actually using:
=REGEXREPLACE("bob@acme.com","^(.)[^@]*","$1***") → b***@acme.com
Keep the first character, replace the rest of the local part. No lookaround required. We ran it. Four years late, but it works.
So what do you do
Never paste a formula straight from a web page into a cell. Paste it into a plain text editor first — Notepad, TextEdit, the formula bar of a blank sheet — and look at the quotation marks. If they lean, retype them.
Count your backslashes. If a pattern contains d{2} or w+ or s where you would expect \d{2}
or \w+ or \s, the page lost them. This is not rare, and it is not the author’s fault: it is what
some publishing systems do to a backslash.
Test the failure, not the success. An email pattern that accepts user@domain.com proves
nothing. Feed it user@domainXcom. A date pattern that accepts 01/02/2026 proves nothing until it
rejects ab/cd/efgh. The patterns that lose a backslash keep working on the happy path, which is
exactly why nobody notices.
The tester on this site now flags a curly quote in a pattern, because we measured what one does: it becomes an ordinary character and matches itself, silently.
What this changed about us
We built this site on the premise that published spreadsheet advice is unreliable and that running it is the only way to know. The first serious test of that premise found sixty patterns that all work.
That is a result, and we are publishing it, because the alternative was to go looking for patterns that fit the headline. The harness exists to stop exactly that. Below is every formula we ran, the value Google returned, and the date it ran.
The run
Nothing above was typed from memory. Here is every formula, and the value Google returned.
Execution log
Sixty regular expressions, copied from Google Sheets tutorials, run in a real sheet
| Cell | Formula | What Google returned |
|---|---|---|
| B1 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","this(.*)that") REGEXEXTRACT: this(.*)that Published at https://www.statology.org/google-sheets-extract-text-between-two-characters/ — "Extract text between two literal string delimiters" | TRUE |
| B2 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","ran(.*)miles") REGEXEXTRACT: ran(.*)miles Published at https://www.statology.org/google-sheets-extract-text-between-two-characters/ — "Capture content between two specific words" | TRUE |
| B3 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\((.*)\)") REGEXEXTRACT: \((.*)\) Published at https://www.statology.org/google-sheets-extract-text-between-two-characters/ — "Extract text enclosed within parentheses" | TRUE |
| B4 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\*(.*)\*") REGEXEXTRACT: \*(.*)\* Published at https://www.statology.org/google-sheets-extract-text-between-two-characters/ — "Extract text between asterisk characters" | TRUE |
| B5 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\w*)\s(\d+)") REGEXEXTRACT: (\w*)\s(\d+) Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Return both a word and the following digits as two capture groups" | TRUE |
| B6 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\w*)") REGEXEXTRACT: (\w*) Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Pull out the first word" | TRUE |
| B7 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(.+)") REGEXEXTRACT: (.+) Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Match and capture all content of a cell" | TRUE |
| B8 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[0-9]+") REGEXEXTRACT: [0-9]+ Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Extract one or more digits" | TRUE |
| B9 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[A-Z]") REGEXEXTRACT: [A-Z] Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Find the first capital letter" | TRUE |
| B10 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[a-z]") REGEXEXTRACT: [a-z] Published at https://officewheel.com/google-sheets-regexextract-between-two-characters/ — "Find the first lowercase letter" | TRUE |
| B11 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") REGEXMATCH: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ Published at https://www.finoptimal.com/resources/regex-extract-in-google-sheets-a-power-users-guide-to-string-manipulation — "Validate that a string is a well-formed email address" | FALSE |
| B12 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^\(\d{3}\) \d{3}-\d{4}$") REGEXMATCH: ^\(\d{3}\) \d{3}-\d{4}$ Published at https://www.finoptimal.com/resources/regex-extract-in-google-sheets-a-power-users-guide-to-string-manipulation — "Validate a US phone number in (XXX) XXX-XXXX format" | FALSE |
| B13 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}") REGEXEXTRACT: [A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,} Published at https://www.sheetfx.net/blog/clean-names-and-emails-regexextract-split-google-sheets — "Extract a standard email address from within a text string" | FALSE |
| B14 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","([^@]+)") REGEXEXTRACT: ([^@]+) Published at https://www.formulabot.com/google-sheets/regexextract-function — "Extract the username portion (before @) from an email address" | TRUE |
| B15 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(.+)@") REGEXEXTRACT: (.+)@ Published at https://productivityspot.com/regexextract-google-sheets/ — "Extract the content before the @ symbol (email username)" | TRUE |
| B16 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","@(.+)") REGEXEXTRACT: @(.+) Published at https://productivityspot.com/regexextract-google-sheets/ — "Extract the domain part (after @) from an email address" | TRUE |
| B17 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","@(.+)$") REGEXEXTRACT: @(.+)$ Published at https://www.owox.com/blog/articles/regex-functions-google-sheets — "Extract the domain name after @ from an email address" | TRUE |
| B18 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith",">(.+)<") REGEXEXTRACT: >(.+)< Published at https://productivityspot.com/regexextract-google-sheets/ — "Extract the text enclosed between a > and a < character" | TRUE |
| B19 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(http|https)://[a-zA-Z0-9./?=_-]+") REGEXEXTRACT: (http|https)://[a-zA-Z0-9./?=_-]+ Published at https://www.bardeen.ai/answers/how-to-extract-urls-and-links-from-google-sheets — "Extract an HTTP/HTTPS URL from a cell of text" | TRUE |
| B20 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\w+)(?:, )(\w+)") REGEXREPLACE: (\w+)(?:, )(\w+) Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Reorder 'Surname, First' to 'First Surname' by swapping two capture groups" | TRUE |
| B21 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d+") REGEXREPLACE: \d+ Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Replace every run of digits with the literal 2021" | TRUE |
| B22 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\d{2})-(\d{2})-(\d{4})") REGEXREPLACE: (\d{2})-(\d{2})-(\d{4}) Published at https://www.thebricks.com/resources/how-to-use-regexreplace-in-google-sheets-a-step-by-step-guide — "Reformat MM-DD-YYYY date to YYYY-MM-DD by rearranging capture groups" | FALSE |
| B23 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","dog") REGEXREPLACE: dog Published at https://www.thebricks.com/resources/how-to-use-regexreplace-in-google-sheets-a-step-by-step-guide — "Replace the word dog with cat" | FALSE |
| B24 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^0-9]") REGEXREPLACE: [^0-9] Published at https://www.thebricks.com/resources/how-to-use-regexreplace-in-google-sheets-a-step-by-step-guide — "Strip all non-digit characters from a phone number" | TRUE |
| B25 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith"," .*") REGEXREPLACE: .* Published at https://www.thebricks.com/resources/how-to-use-regexreplace-in-google-sheets-a-step-by-step-guide — "Keep only the first name by deleting everything from the first space onward" | TRUE |
| B26 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^https?:\/\/") REGEXREPLACE: ^https?:\/\/ Published at https://www.thebricks.com/resources/how-to-use-regexreplace-in-google-sheets-a-step-by-step-guide — "Remove the http:// or https:// protocol prefix from a URL" | FALSE |
| B27 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","S.*d") REGEXREPLACE: S.*d Published at https://support.google.com/docs/answer/3098245?hl=en — "Replace the substring from S to the last d with the literal Bed" | FALSE |
| B28 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^\d]") REGEXREPLACE: [^\d] Published at https://smoothsheet.com/blog/how-to/google-sheets-regex/ — "Remove all non-digit characters from a phone number" | TRUE |
| B29 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\d{2})/(\d{2})/(\d{4})") REGEXREPLACE: (\d{2})/(\d{2})/(\d{4}) Published at https://smoothsheet.com/blog/how-to/google-sheets-regex/ — "Convert MM/DD/YYYY date to YYYY-MM-DD via capture-group rearrangement" | TRUE |
| B30 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","<[^>]+>") REGEXREPLACE: <[^>]+> Published at https://smoothsheet.com/blog/how-to/google-sheets-regex/ — "Strip all HTML tags from text" | TRUE |
| B31 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^(\w+)\s(\w+)$") REGEXREPLACE: ^(\w+)\s(\w+)$ Published at https://unlimitedsheets.com/blog/regex — "Reorder 'First Last' into 'Last, First' by swapping capture groups" | FALSE |
| B32 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(?i)([a-z0-9._%+\-]+)@") REGEXREPLACE: (?i)([a-z0-9._%+\-]+)@ Published at https://unlimitedsheets.com/blog/regex — "Mask the local part of an email address before the @ sign" | TRUE |
| B33 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","colour") REGEXREPLACE: colour Published at https://unlimitedsheets.com/blog/regex — "Nest REGEXREPLACE to normalize British spellings colour/favour to American" | FALSE |
| B34 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d[\d,.]*") REGEXEXTRACT: \d[\d,.]* Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Extract a number that may contain commas or decimals and convert to numeric" | TRUE |
| B35 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\b\d{3}-\d{3}-\d{4}\b") REGEXMATCH: \b\d{3}-\d{3}-\d{4}\b Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Validate a US phone number in XXX-XXX-XXXX format" | FALSE |
| B36 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\b[0-9]{4}\b") REGEXMATCH: \b[0-9]{4}\b Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Validate a 4-digit number (e.g. a year/vintage) with word boundaries" | TRUE |
| B37 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$") REGEXMATCH: ^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$ Published at https://unlimitedsheets.com/blog/regex — "Validate whether a cell looks like a valid email address" | FALSE |
| B38 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^\d{10}$") REGEXMATCH: ^\d{10}$ Published at https://unlimitedsheets.com/blog/regex — "Validate a phone number as exactly 10 digits" | FALSE |
| B39 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^https?://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(/.*)?$") REGEXMATCH: ^https?://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(/.*)?$ Published at https://unlimitedsheets.com/blog/regex — "Validate that a URL starts with http/https, has a valid domain and optional path" | FALSE |
| B40 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d{4}-\d{3}-\d{4}") REGEXMATCH: \d{4}-\d{3}-\d{4} Published at https://blog.bettersheets.co/philippines-phone-number-validation-use-of-regexmatch-in-google-sheets/ — "Validate a Philippine phone number in the XXXX-XXX-XXXX format" | FALSE |
| B41 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[0-9]{5}") REGEXEXTRACT: [0-9]{5} Published at https://www.coursera.org/articles/regex-match-google-sheets — "Extract/match text of exactly five digits (ZIP code)" | FALSE |
| B42 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","^[a-z]+$") REGEXMATCH: ^[a-z]+$ Published at https://www.usemage.com/google-sheets-how-to/how-to-use-regular-expressions-in-google-sheets — "Check if a value contains only lowercase letters" | FALSE |
| B43 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^\x00-\x7F]") REGEXREPLACE: [^\x00-\x7F] Published at https://sheetsformarketers.com/1text-formatting-in-google-sheets/ — "Remove all non-ASCII (non-English/accented/foreign) characters from a string" | FALSE |
| B44 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^0-9A-Za-z]") REGEXREPLACE: [^0-9A-Za-z] Published at https://sheetsformarketers.com/1text-formatting-in-google-sheets/ — "Remove everything that is not an English letter or digit" | TRUE |
| B45 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^\x20-\x7E]") REGEXREPLACE: [^\x20-\x7E] Published at https://sheetsformarketers.com/1text-formatting-in-google-sheets/ — "Strip emojis and non-printable/non-ASCII characters, keeping printable ASCII" | FALSE |
| B46 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^A-Za-z]+") REGEXREPLACE: [^A-Za-z]+ Published at https://scales.arabpsychology.com/stats/how-to-remove-special-characters-in-google-sheets/ — "Keep only English alphabet letters, removing numbers, symbols and non-English characters" | TRUE |
| B47 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[^0-9a-zA-Z]") REGEXREPLACE: [^0-9a-zA-Z] Published at https://scales.arabpsychology.com/stats/how-to-remove-special-characters-in-google-sheets/ — "Keep English letters and digits, remove all special/non-English characters" | TRUE |
| B48 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[!$%]") REGEXREPLACE: [!$%] Published at https://scales.arabpsychology.com/stats/how-to-remove-special-characters-in-google-sheets/ — "Remove only the specific symbols exclamation point, dollar sign and percent sign" | FALSE |
| B49 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[áàâäãå]") REGEXREPLACE: [áàâäãå] Published at https://en.digitalmalayali.in/remove-accents-in-google-sheets-functions-regex-script/ — "Replace accented a-vowels with plain 'a'" | FALSE |
| B50 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[éèêë]") REGEXREPLACE: [éèêë] Published at https://en.digitalmalayali.in/remove-accents-in-google-sheets-functions-regex-script/ — "Replace accented e-vowels with plain 'e'" | FALSE |
| B51 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[0-9]") REGEXMATCH: [0-9] Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Return TRUE if the string contains any digit" | TRUE |
| B52 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d+") REGEXEXTRACT: \d+ Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Extract the first sequence of digits from a string" | TRUE |
| B53 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[\d,.]+") REGEXEXTRACT: [\d,.]+ Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Extract numbers that may include thousand separators or decimals" | TRUE |
| B54 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d{3}-\d{3}-\d{4}") REGEXMATCH: \d{3}-\d{3}-\d{4} Published at https://www.benlcollins.com/spreadsheets/google-sheets-regex-formulas/ — "Validate a phone number in ###-###-#### form using quantifiers" | FALSE |
| B55 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","fun|terrifying") REGEXEXTRACT: fun|terrifying Published at https://sheets-pratique.com/en/functions/regexextract — "Extract whichever of two alternative words appears first" | FALSE |
| B56 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","[A-Z]\d{2}") REGEXEXTRACT: [A-Z]\d{2} Published at https://sheets-pratique.com/en/functions/regexextract — "Extract a reference code of one uppercase letter followed by two digits" | FALSE |
| B57 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d*") REGEXEXTRACT: \d* Published at https://sheets-pratique.com/en/functions/regexextract — "Extract leading digits until a non-digit character is reached" | TRUE |
| B58 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d*$") REGEXEXTRACT: \d*$ Published at https://sheets-pratique.com/en/functions/regexextract — "Extract the digits at the end of the text" | TRUE |
| B59 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","(\d*)-?(\d*)-?(\d*)-?(\d*)") REGEXEXTRACT: (\d*)-?(\d*)-?(\d*)-?(\d*) Published at https://sheets-pratique.com/en/functions/regexextract — "Split a hyphen-separated string into separate digit groups" | TRUE |
| B60 | =REGEXMATCH("Order 4821 <b>ran 5 miles</b> john.doe@acme.com https://x.io/y (paren) *star* this Z that 01/02/2026 John, Smith","\d*-(\d*)") REGEXEXTRACT: \d*-(\d*) Published at https://sheets-pratique.com/en/functions/regexextract — "Capture the second group of digits after a hyphen" | FALSE |
| B61 | =REGEXMATCH("01/02/2026","^d{2}/d{2}/d{4}$") published verbatim: backslashes stripped by the page Exactly as printed at https://coefficient.io/google-sheets-tutorials/regexmatch-in-google-sheets-2 | FALSE |
| B62 | =REGEXMATCH("01/02/2026","^\d{2}/\d{2}/\d{4}$") the same pattern with the backslashes the author meant What a reader would have to reconstruct to make the published advice work. | TRUE |
| B63 | =REGEXMATCH(“abc”,“b”) transmission: a formula printed with typographic quotes Exactly what lands in the cell when you copy a formula from a page that curls its quotes. | #ERROR! |
| B64 | =REGEXMATCH("abc","b") transmission: the same formula with straight quotes The control. Identical in every way a person can see. | TRUE |
| B65 | =REGEXMATCH("user@domainXcom","^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$") transmission: email pattern as published, backslash gone, against a bad address The dot lost its backslash and now matches any character. domainXcom has no dot in it. | TRUE |
| B66 | =REGEXMATCH("user@domainXcom","^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") transmission: email pattern with the backslash restored, against the same bad address What the author wrote before the page ate it. | FALSE |
| B67 | =REGEXMATCH("user@domain.com","^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$") transmission: email pattern as published, against a real address It works here, which is why nobody notices. | TRUE |
| B68 | =REGEXREPLACE("bob@acme.com","/(?!^).(?=[^@]+@)/","*") transmission: a JavaScript regex pasted into Sheets, slashes and all Verbatim from a reader comment dated 2022-07-27: "Not working… What am I missing?" | #REF! |
| B69 | =REGEXREPLACE("bob@acme.com","(?!^).(?=[^@]+@)","*") transmission: the same pattern with the JavaScript slashes removed Removing the delimiters does not save it. The lookaheads are the problem. | #REF! |
| B70 | =REGEXREPLACE("bob@acme.com","^(.)[^@]*","$1***") transmission: what he wanted, written for RE2 Keep the first character, replace the rest of the local part. No lookaround required. | b***@acme.com |
| B71 | =REGEXMATCH("abc","“abc”") curly inside the pattern: does it match the plain text What happens when a reader copies the quote marks along with the pattern into a tester. | FALSE |
| B72 | =REGEXMATCH("“abc”","“abc”") curly inside the pattern: does it match text that has the curly quotes too It is a literal character, not a delimiter. It matches itself. | TRUE |
| B73 | =REGEXMATCH("abc","abc") curly inside the pattern: the straight-quoted control The pattern the reader meant. | TRUE |
Every row above was written into a real Google Sheet and read back through the Sheets API on 2026-07-09. The case file and this log are in the repository, and the build refuses to run if they disagree.
Execution log
What Google Sheets regex actually supports, and what it silently does instead
| Cell | Formula | What Google returned |
|---|---|---|
| B1 | =REGEXMATCH("abc123","\d+") baseline: REGEXMATCH finds digits Sanity check. If this fails, the harness itself is broken. | TRUE |
| B2 | =REGEXEXTRACT("Order 4821 shipped","\d+") baseline: REGEXEXTRACT pulls the first match | 4821 |
| B3 | =REGEXREPLACE("John Smith","(\w+) (\w+)","$2 $1") baseline: REGEXREPLACE swaps groups with $1 / $2 Dollar-sign backreferences are the Sheets replacement syntax. | Smith John |
| B4 | =REGEXMATCH("abc123","abc(?=123)") RE2 limit: positive lookahead (?=...) Works on regex101. Here it is not #ERROR! — it is #REF!, the error people associate with a deleted cell reference. That is why they hunt for a typo that does not exist. | #REF! |
| B5 | =REGEXMATCH("abc","a(?!b)") RE2 limit: negative lookahead (?!...) | #REF! |
| B6 | =REGEXMATCH("abc123","(?<=abc)123") RE2 limit: lookbehind (?<=...) | #REF! |
| B7 | =REGEXMATCH("abab","(ab)\1") RE2 limit: backreference inside the pattern Backreferences exist in the REPLACEMENT string of REGEXREPLACE, but never in the pattern. | #REF! |
| B8 | =REGEXMATCH("héllo","\p{L}+") Sheets limit: Unicode character class \p{L} RE2 supports this. Google Sheets is the exception Google names in its own docs. This one catches people who already know RE2. | #REF! |
| B9 | =REGEXMATCH("abc","(abc") unbalanced parenthesis is also #REF!, not #ERROR! A malformed regex and an unsupported one produce the same error. The cell tells you nothing about which. | #REF! |
| B10 | =ERROR.TYPE(REGEXMATCH("abc123","abc(?=123)")) cross-check: ERROR.TYPE of an unsupported pattern Independent confirmation of the error type. ERROR.TYPE returns 4 for #REF!, 3 for #VALUE!, 7 for #N/A, 8 for #ERROR!. We do not take one measurement's word for it. | 4 |
| B11 | =ERROR.TYPE(REGEXEXTRACT("abc","\d")) cross-check: ERROR.TYPE of REGEXEXTRACT with no match | 7 |
| B12 | =IFERROR(REGEXMATCH("abc123","abc(?=123)"),"caught") an unsupported pattern is catchable with IFERROR If IFERROR swallows it, a broken pattern can hide inside a working-looking spreadsheet forever. | caught |
| B13 | =REGEXEXTRACT("abc","\d") REGEXEXTRACT with no match A different error from an invalid pattern. People wrap both in IFERROR without noticing. | #N/A |
| B14 | =REGEXMATCH("cat dog","\bdog\b") supported: word boundary \b | TRUE |
| B15 | =REGEXEXTRACT("<a><b>","<(.+?)>") supported: lazy quantifier +? | a |
| B16 | =REGEXMATCH("ABC","(?i)abc") supported: inline case-insensitive flag (?i) | TRUE |
| B17 | =REGEXEXTRACT("x=1","(?P<digit>\d)") supported: RE2 named capture group (?P<name>...) RE2's own spelling. | 1 |
| B18 | =REGEXEXTRACT("x=1","(?<digit>\d)") supported: JavaScript named group syntax (?<name>...) also works Measured, not assumed. Sheets accepts both spellings, and ignores the name either way — REGEXEXTRACT returns groups in order. | 1 |
| B19 | =REGEXREPLACE("John Smith","(\w+) (\w+)","\2 \1") trap: backslash backreference in the replacement string No error. The backslashes vanish and you are left with the literal digits. Worse than an error, because an error tells you to stop. | 2 1 |
| B20 | =REGEXREPLACE("abc","b","[$0]") trap: $0 is the whole match in the replacement string | a[b]c |
| B21 | =REGEXREPLACE("abc","b","[$1]") trap: $1 when the pattern has no capture group It is an error, not a silent empty string. We did not know, so we measured. | #N/A |
Every row above was written into a real Google Sheet and read back through the Sheets API on 2026-07-09. The case file and this log are in the repository, and the build refuses to run if they disagree.
When a new pattern gets verified, I'll tell you
One email when a new formula is executed, logged, and published. Nothing else. Unsubscribe in one click.