← All functions

REGEXREPLACE

Quirk found

Category: Text · Last tested 2026-09-01

Real compatibility results for the REGEXREPLACE function: executed in Excel for the web, Google Sheets and LibreOffice Calc, with desktop Excel behavior from Microsoft’s official documentation (we do not run desktop Excel — Excel for the web is a different application and is executed separately). Syntax and links to that documentation are below.

Support matrix

EngineDocumentedLive-testedVerdict
Excel (desktop)Yes No — documented only n/a
Excel for the web— Yes (recalc, 2026-09-01) Supported, behaves as documented
Google SheetsYes Yes (Drive import, 2026-08-31) Quirk found
LibreOffice CalcNo Yes (25.8.7.3, 2026-08-31) Unsupported (not recognized)

LibreOffice version history

We executed the same test cases under each LibreOffice release to show exactly when REGEXREPLACE’s support changed — not documentation claims, real results.

LibreOffice versionVerdictTested
24.2.0.3 Unsupported (not recognized) 2026-08-31
24.8.7.2 Unsupported (not recognized) 2026-08-31
25.2.0.3 Unsupported (not recognized) 2026-08-31
25.8.7.3 Unsupported (not recognized) 2026-08-31

Why isn't REGEXREPLACE working in LibreOffice?

LibreOffice Calc does not implement REGEXREPLACE as of 25.8.7.3 — in our executed tests it returns a #NAME? (unrecognized function) error. This is not a typo or a settings problem, and saving the file as .xlsx does not change it: the function simply isn’t available yet. The same formula is documented for Excel and documented for Google Sheets. Watch the LibreOffice version support page — we re-run every test on each new release, so it will flip to Supported here as soon as it lands.

Why isn’t REGEXREPLACE working in Google Sheets?

REGEXREPLACE runs in Google Sheets, but our executed cases show it does not match Excel’s documented behavior on every input (the failing cases are listed on this page). If a formula that behaves one way in Excel gives you a different answer in Sheets, compare your usage against those cases before assuming your data is wrong.

Discovered quirks

Executed test cases

Excel for the web (executed 2026-09-01 via OneDrive recalculation)

These values come from Excel for the web, not from desktop Excel. They are two different implementations of the calculation engine, and this run measured only the web one: the corpus was uploaded to OneDrive as .xlsx, recalculated by Excel for the web on open, and downloaded again for readback. Excel for the web is a rolling service with no pinnable version, so the run is identified by its date. Where a value here disagrees with the Expected column — which is Microsoft’s documentation of the desktop product — we cannot tell you whether the web engine diverges from the desktop one or the documentation is wrong about both, because we do not run desktop Excel.

FormulaDescriptionResultExpectedVerdict
=REGEXREPLACE(A2,"[0-9]+-","***-") Microsoft's documented example: masking the middle block of a phone number (378) ***-4195 (378) ***-4195
Provenance

Microsoft's Example 1 uses exactly this pattern -- "Use REGEXREPLACE to anonymize phone numbers by replacing their first 3 digits with ***, using pattern [0-9]+-" -- over a block of names and numbers. DERIVATION on one line of that data: "[0-9]+-" matches a run of digits followed by a hyphen. In "(378) 555-4195" the only such run is "555-" (the "378" is followed by ")", and "4195" ends the string), so it alone is replaced by "***-", giving "(378) ***-4195". REGEX FLAVOUR, AS DOCUMENTED: "All regular expressions for this function, as well as REGEXTEST and REGEXREPLACE use the PCRE2 'flavor' of regex" -- Microsoft's own sentence, printed on all three REGEX pages. This corpus's patterns are deliberately confined to character classes, quantifiers and anchors, which mean the same thing in PCRE2, in RE2 and in the ICU flavour LibreOffice's own REGEX function documents, so a difference between engines here is a difference about the FUNCTION, not about dialect corners. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/regexreplace-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- GENUINELY ABSENT: LibreOffice returns #NAME? on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case, under all four spellings probed before the run (plain, _xlfn., COM.MICROSOFT. and ORG.OPENOFFICE.). None of the three Excel REGEX functions exists in any LibreOffice release tested here. LibreOffice is not without regular expressions -- its own REGEX(Text; Expression [; [Replacement] [; Flags|Occurrence]]) is documented and works -- but it is a different function with a different name, a different argument shape and a different flavour (ICU, against the PCRE2 Microsoft's pages name), so a workbook using REGEXTEST or REGEXEXTRACT does not open and run; it has to be rewritten.

Matched
=REGEXREPLACE("a1b2c3","[0-9]","#") The documented default occurrence of 0, which replaces all instances a#b#c# a#b#c#
Provenance

Microsoft documents: "By default, occurrence is 0, which replaces all instances." All three digits in "a1b2c3" are replaced, giving "a#b#c#" -- an engine that replaced only the first would return "a#b2c3", which is the single most likely difference between two implementations of this function and is why the default is asserted explicitly.

Matched
=REGEXREPLACE("a1b2c3","[0-9]","#",-1) The documented negative-occurrence rule a1b2c# a1b2c#
Provenance

Microsoft documents: "A negative number replaces that instance, searching from the end." So -1 is the LAST digit, the 3, and only it is replaced: "a1b2c#". This is an unusual convention -- most regex APIs have no notion of it at all -- which makes it a good probe of whether an engine implemented Excel's documented argument or borrowed a host language's replace-all/replace-first semantics.

Matched
=REGEXREPLACE("Apple apple","apple","X",0,1) The documented case_sensitivity argument set to case-insensitive X X X X
Provenance

Microsoft documents case_sensitivity as "0: Case sensitive" (default) and "1: Case insensitive". With 1, the literal pattern "apple" matches both "Apple" and "apple", so both are replaced and the answer is "X X"; with the default it would be "Apple X". Note the fifth argument requires the fourth, so occurrence is passed explicitly as its documented default of 0.

Matched
=REGEXREPLACE("abc","[0-9]","#") A pattern that matches nothing abc abc
Provenance

Nothing matches, so there is nothing to replace and the text comes back unchanged. This is the one place where the REGEX family does NOT return #N/A on a failed match -- REGEXEXTRACT does, because it has nothing to return, while a replacement over zero matches is simply the identity -- and asserting it here pins that difference. LibreOffice's own REGEX function documents the same behaviour ("if a replacement is given and no match occurs, the original text is returned unchanged").

Matched

Google Sheets (executed 2026-08-31 via Drive import)

Google Sheets is a rolling service with no pinnable version, so this run is identified by its date. The corpus was imported to Drive as .xlsx, recalculated by Sheets, and exported back for readback.

FormulaDescriptionResultExpectedVerdict
=REGEXREPLACE(A2,"[0-9]+-","***-") Microsoft's documented example: masking the middle block of a phone number (378) ***-4195 (378) ***-4195
Provenance

Microsoft's Example 1 uses exactly this pattern -- "Use REGEXREPLACE to anonymize phone numbers by replacing their first 3 digits with ***, using pattern [0-9]+-" -- over a block of names and numbers. DERIVATION on one line of that data: "[0-9]+-" matches a run of digits followed by a hyphen. In "(378) 555-4195" the only such run is "555-" (the "378" is followed by ")", and "4195" ends the string), so it alone is replaced by "***-", giving "(378) ***-4195". REGEX FLAVOUR, AS DOCUMENTED: "All regular expressions for this function, as well as REGEXTEST and REGEXREPLACE use the PCRE2 'flavor' of regex" -- Microsoft's own sentence, printed on all three REGEX pages. This corpus's patterns are deliberately confined to character classes, quantifiers and anchors, which mean the same thing in PCRE2, in RE2 and in the ICU flavour LibreOffice's own REGEX function documents, so a difference between engines here is a difference about the FUNCTION, not about dialect corners. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/regexreplace-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- GENUINELY ABSENT: LibreOffice returns #NAME? on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case, under all four spellings probed before the run (plain, _xlfn., COM.MICROSOFT. and ORG.OPENOFFICE.). None of the three Excel REGEX functions exists in any LibreOffice release tested here. LibreOffice is not without regular expressions -- its own REGEX(Text; Expression [; [Replacement] [; Flags|Occurrence]]) is documented and works -- but it is a different function with a different name, a different argument shape and a different flavour (ICU, against the PCRE2 Microsoft's pages name), so a workbook using REGEXTEST or REGEXEXTRACT does not open and run; it has to be rewritten.

Matched
=REGEXREPLACE("a1b2c3","[0-9]","#") The documented default occurrence of 0, which replaces all instances a#b#c# a#b#c#
Provenance

Microsoft documents: "By default, occurrence is 0, which replaces all instances." All three digits in "a1b2c3" are replaced, giving "a#b#c#" -- an engine that replaced only the first would return "a#b2c3", which is the single most likely difference between two implementations of this function and is why the default is asserted explicitly.

Matched
=REGEXREPLACE("a1b2c3","[0-9]","#",-1) The documented negative-occurrence rule #N/A a1b2c#
Provenance

Microsoft documents: "A negative number replaces that instance, searching from the end." So -1 is the LAST digit, the 3, and only it is replaced: "a1b2c#". This is an unusual convention -- most regex APIs have no notion of it at all -- which makes it a good probe of whether an engine implemented Excel's documented argument or borrowed a host language's replace-all/replace-first semantics.

Mismatch
=REGEXREPLACE("Apple apple","apple","X",0,1) The documented case_sensitivity argument set to case-insensitive #N/A X X
Provenance

Microsoft documents case_sensitivity as "0: Case sensitive" (default) and "1: Case insensitive". With 1, the literal pattern "apple" matches both "Apple" and "apple", so both are replaced and the answer is "X X"; with the default it would be "Apple X". Note the fifth argument requires the fourth, so occurrence is passed explicitly as its documented default of 0.

Mismatch
=REGEXREPLACE("abc","[0-9]","#") A pattern that matches nothing abc abc
Provenance

Nothing matches, so there is nothing to replace and the text comes back unchanged. This is the one place where the REGEX family does NOT return #N/A on a failed match -- REGEXEXTRACT does, because it has nothing to return, while a replacement over zero matches is simply the identity -- and asserting it here pins that difference. LibreOffice's own REGEX function documents the same behaviour ("if a replacement is given and no match occurs, the original text is returned unchanged").

Matched

LibreOffice Calc 25.8.7.3 (tested 2026-08-31)

FormulaDescriptionResultExpectedVerdict
=REGEXREPLACE(A2,"[0-9]+-","***-") Microsoft's documented example: masking the middle block of a phone number #NAME? (378) ***-4195
Provenance

Microsoft's Example 1 uses exactly this pattern -- "Use REGEXREPLACE to anonymize phone numbers by replacing their first 3 digits with ***, using pattern [0-9]+-" -- over a block of names and numbers. DERIVATION on one line of that data: "[0-9]+-" matches a run of digits followed by a hyphen. In "(378) 555-4195" the only such run is "555-" (the "378" is followed by ")", and "4195" ends the string), so it alone is replaced by "***-", giving "(378) ***-4195". REGEX FLAVOUR, AS DOCUMENTED: "All regular expressions for this function, as well as REGEXTEST and REGEXREPLACE use the PCRE2 'flavor' of regex" -- Microsoft's own sentence, printed on all three REGEX pages. This corpus's patterns are deliberately confined to character classes, quantifiers and anchors, which mean the same thing in PCRE2, in RE2 and in the ICU flavour LibreOffice's own REGEX function documents, so a difference between engines here is a difference about the FUNCTION, not about dialect corners. Microsoft's page was re-read live on 2026-08-31 at https://support.microsoft.com/en-us/excel/functions/regexreplace-function (the /en-us/office/<name>-function-<guid> path was returning Microsoft's 'Sorry, the page you're looking for can't be found' body throughout this batch, and the working path serves an 87 KB stub about half the time, so pages were fetched with retries until the payload exceeded 150 KB). EXECUTED RESULT -- GENUINELY ABSENT: LibreOffice returns #NAME? on all four pinned builds (24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3), which agree case for case, under all four spellings probed before the run (plain, _xlfn., COM.MICROSOFT. and ORG.OPENOFFICE.). None of the three Excel REGEX functions exists in any LibreOffice release tested here. LibreOffice is not without regular expressions -- its own REGEX(Text; Expression [; [Replacement] [; Flags|Occurrence]]) is documented and works -- but it is a different function with a different name, a different argument shape and a different flavour (ICU, against the PCRE2 Microsoft's pages name), so a workbook using REGEXTEST or REGEXEXTRACT does not open and run; it has to be rewritten.

Mismatch
=REGEXREPLACE("a1b2c3","[0-9]","#") The documented default occurrence of 0, which replaces all instances #NAME? a#b#c#
Provenance

Microsoft documents: "By default, occurrence is 0, which replaces all instances." All three digits in "a1b2c3" are replaced, giving "a#b#c#" -- an engine that replaced only the first would return "a#b2c3", which is the single most likely difference between two implementations of this function and is why the default is asserted explicitly.

Mismatch
=REGEXREPLACE("a1b2c3","[0-9]","#",-1) The documented negative-occurrence rule #NAME? a1b2c#
Provenance

Microsoft documents: "A negative number replaces that instance, searching from the end." So -1 is the LAST digit, the 3, and only it is replaced: "a1b2c#". This is an unusual convention -- most regex APIs have no notion of it at all -- which makes it a good probe of whether an engine implemented Excel's documented argument or borrowed a host language's replace-all/replace-first semantics.

Mismatch
=REGEXREPLACE("Apple apple","apple","X",0,1) The documented case_sensitivity argument set to case-insensitive #NAME? X X
Provenance

Microsoft documents case_sensitivity as "0: Case sensitive" (default) and "1: Case insensitive". With 1, the literal pattern "apple" matches both "Apple" and "apple", so both are replaced and the answer is "X X"; with the default it would be "Apple X". Note the fifth argument requires the fourth, so occurrence is passed explicitly as its documented default of 0.

Mismatch
=REGEXREPLACE("abc","[0-9]","#") A pattern that matches nothing #NAME? abc
Provenance

Nothing matches, so there is nothing to replace and the text comes back unchanged. This is the one place where the REGEX family does NOT return #N/A on a failed match -- REGEXEXTRACT does, because it has nothing to return, while a replacement over zero matches is simply the identity -- and asserting it here pins that difference. LibreOffice's own REGEX function documents the same behaviour ("if a replacement is given and no match occurs, the original text is returned unchanged").

Mismatch

Docs & syntax

Related how-to recipes

Where REGEXREPLACE behaves differently