REGEXREPLACE
Quirk foundCategory: 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
| Engine | Documented | Live-tested | Verdict |
|---|---|---|---|
| Excel (desktop) | Yes | No — documented only | n/a |
| Excel for the web | — | Yes (recalc, 2026-09-01) | Supported, behaves as documented |
| Google Sheets | Yes | Yes (Drive import, 2026-08-31) | Quirk found |
| LibreOffice Calc | No | 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 version | Verdict | Tested |
|---|---|---|
| 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
-
=REGEXREPLACE("a1b2c3","[0-9]","#",-1) on
Google Sheets returned
#N/A, but the documented/expected
result is 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 vs expected: expected 'a1b2c#', got '#N/A'
-
=REGEXREPLACE("Apple apple","apple","X",0,1) on
Google Sheets returned
#N/A, but the documented/expected
result is 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 vs expected: expected 'X X', got '#N/A'
-
=REGEXREPLACE(A2,"[0-9]+-","***-") on
LibreOffice Calc returned
#NAME?, but the documented/expected
result is (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 vs expected: expected '(378) ***-4195', got '#NAME?'
-
=REGEXREPLACE("a1b2c3","[0-9]","#") on
LibreOffice Calc returned
#NAME?, but the documented/expected
result is 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 vs expected: expected 'a#b#c#', got '#NAME?'
-
=REGEXREPLACE("a1b2c3","[0-9]","#",-1) on
LibreOffice Calc returned
#NAME?, but the documented/expected
result is 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 vs expected: expected 'a1b2c#', got '#NAME?'
-
=REGEXREPLACE("Apple apple","apple","X",0,1) on
LibreOffice Calc returned
#NAME?, but the documented/expected
result is 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 vs expected: expected 'X X', got '#NAME?'
-
=REGEXREPLACE("abc","[0-9]","#") on
LibreOffice Calc returned
#NAME?, but the documented/expected
result is 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 vs expected: expected 'abc', got '#NAME?'
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.
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =REGEXREPLACE(A2,"[0-9]+-","***-") | Microsoft's documented example: masking the middle block of a phone number | (378) ***-4195 | (378) ***-4195ProvenanceMicrosoft'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#ProvenanceMicrosoft 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#ProvenanceMicrosoft 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 XProvenanceMicrosoft 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 | abcProvenanceNothing 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.
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =REGEXREPLACE(A2,"[0-9]+-","***-") | Microsoft's documented example: masking the middle block of a phone number | (378) ***-4195 | (378) ***-4195ProvenanceMicrosoft'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#ProvenanceMicrosoft 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#ProvenanceMicrosoft 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 XProvenanceMicrosoft 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 | abcProvenanceNothing 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)
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =REGEXREPLACE(A2,"[0-9]+-","***-") | Microsoft's documented example: masking the middle block of a phone number | #NAME? | (378) ***-4195ProvenanceMicrosoft'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#ProvenanceMicrosoft 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#ProvenanceMicrosoft 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 XProvenanceMicrosoft 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? | abcProvenanceNothing 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
- Excel (desktop): official documentation
- Google Sheets: official documentation
Related how-to recipes
Where REGEXREPLACE behaves differently
- Google-only functions: what ports to Excel and LibreOffice, and what does not
Executed: 47 functions Google documents and neither Microsoft nor LibreOffice does, 189 cases, 183 of them #NAME? in LibreOffice on all four pinned builds after five- and nine-spelling probes. QUERY and ARRAYFORMULA do not port; the operator functions do exactly; REGEXMATCH, REGEXTEST and REGEX are three different functions with three regex flavours.