REGEX
Unsupported (not recognized)Category: Text · Last tested 2026-09-01
Real compatibility results for the REGEX function: executed in Excel for the web, Google Sheets and LibreOffice Calc, measured against LibreOffice’s published documentation. Excel does not document REGEX, so this page makes no claim about Excel. Syntax and links to that documentation are below.
Support matrix
| Engine | Documented | Live-tested | Verdict |
|---|---|---|---|
| Excel (desktop) | No | n/a (not an Excel function) | n/a |
| Excel for the web | — | Yes (recalc, 2026-09-01) | Unsupported (not recognized) |
| Google Sheets | No | Yes (Drive import, 2026-09-01) | Unsupported (not recognized) |
| LibreOffice Calc | Yes | Yes (25.8.7.3, 2026-09-01) | Supported, behaves as documented |
LibreOffice version history
We executed the same test cases under each LibreOffice release to show exactly when REGEX’s support changed — not documentation claims, real results.
| LibreOffice version | Verdict | Tested |
|---|---|---|
| 24.2.0.3 | Supported, behaves as documented | 2026-09-01 |
| 24.8.7.2 | Supported, behaves as documented | 2026-09-01 |
| 25.2.0.3 | Supported, behaves as documented | 2026-09-01 |
| 25.8.7.3 | Supported, behaves as documented | 2026-09-01 |
Why isn’t REGEX working in Google Sheets?
Google Sheets does not implement REGEX: we imported the formula into
Sheets on 2026-09-01 and every case came back #NAME?
(unrecognized function). Sheets is a rolling service with no version to pin, so this is a
statement about the service on that date, and Google’s own
function list does not document it either. Rewrite the formula with a documented
Sheets equivalent — see the
Excel ↔ Sheets equivalents table.
Discovered quirks
-
=REGEX("123456ABCDEF","[:digit:]","Z") on
Excel for the web returned
#NAME?, but the documented/expected
result is Z23456ABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z") returns "Z23456ABCDEF", where the first match of a digit is replaced by "Z"." This page is the best-documented in the whole batch -- five worked examples with printed results -- so five of the six cases here are published rather than derived. THE REGEX FLAVOUR IS PART OF THE FINDING AND THE PAGE STATES IT: "Expression: A text representing the regular expression, using ICU regular expressions." That is a different flavour from the PCRE2 that Microsoft's REGEXEXTRACT/REGEXREPLACE/REGEXTEST pages specify, which is why this corpus keeps LibreOffice's REGEX and Microsoft's REGEX* trio as separate functions rather than treating either as the other's alias. Note also that the bracket expression published here is "[:digit:]" -- a bracketed set of the six characters : d g i t, not the POSIX class [[:digit:]] -- which happens to match the digits in this input anyway; the value asserted is the one the page publishes for the expression the page publishes. STORAGE FORM, ESTABLISHED EMPIRICALLY IN BOTH DIRECTIONS BEFORE THIS FILE WAS RUN. A LibreOffice-only function has no OOXML name of its own -- the .xlsx format was frozen on Excel's function set -- so LibreOffice invents one, and this harness must write exactly the token LibreOffice's own .xlsx filter reads. Both directions were measured rather than assumed. IMPORT: every candidate spelling was written into a workbook by openpyxl (which caches no value, so the engine must evaluate from scratch) and round-tripped through `soffice --headless --convert-to xlsx` on all four pinned builds. EXPORT: the same formulas were fed to each build through its own formula parser and written back out to .xlsx, and the stored token was read out of the raw sheet XML. The token recorded for this function in harness/xlfn_map.py is the one both directions agree on across all four builds; the per-function note above says which it is. BATCH PROVENANCE (batch I, group C -- LibreOffice-only functions). This function has x == false AND g == false in docs/data/compat.json: NEITHER Microsoft NOR Google documents it, so this corpus makes no claim about either of those engines, nothing here is measured against their documentation, and the Excel column on the published page reads 'n/a (not an Excel function)' rather than a verdict. The authority is LibreOffice's own help, cited by full URL, by the date it was read (2026-08-31), and by the help version the page serves -- the URLs in this file are pinned to /25.8/ rather than /latest/ so the citation still means this text after the help site rolls forward, and /25.8/ is the help for the newest of the four engine builds the corpus executes. GOOGLE SHEETS: this batch builds the Sheets chunk whose ingest will record presence or absence in that engine. Until that ingest lands, the Sheets column on the published page reads 'Not yet' and nothing in this file claims anything about it. (Stated positively on purpose. scripts/check_honesty.py bans the blanket negative shape of this sentence outright -- it was once a true site-wide claim and is now false for more than 500 functions -- and that guard is worth keeping blunt, so this note carries the same per-function fact in a form the guard does not have to make an exception for.) LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'Z23456ABCDEF', got '#NAME?'
-
=REGEX("123456ABCDEF","[:digit:]","Z","g") on
Excel for the web returned
#NAME?, but the documented/expected
result is ZZZZZZABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z";"g") returns "ZZZZZZABCDEF", where all digits were replaced by "Z"." Matches the documented Flags parameter: "'g' replaces all matches of Expression in Text, not extracted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'ZZZZZZABCDEF', got '#NAME?'
-
=REGEX("123456ABCDEF","[126]","","g") on
Excel for the web returned
#NAME?, but the documented/expected
result is 345ABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[126]";"";"g") returns "345ABCDEF", where any occurrence of "1", "2" or "6" is replaced by the empty string, thus deleted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected '345ABCDEF', got '#NAME?'
-
=REGEX("axbxcxd",".x",,2) on
Excel for the web returned
#NAME?, but the documented/expected
result is bx.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";".x";;2) returns "bx", the second match of ".x"." The empty third argument is the page's own -- Replacement omitted turns the call from a replace into an extract, per "Occurrence: ... Number to indicate which match of Expression in Text is to be extracted or replaced." It is written here exactly as published, empty argument included. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'bx', got '#NAME?'
-
=REGEX("axbxcxd","(.)x","$1y",2) on
Excel for the web returned
#NAME?, but the documented/expected
result is axbycxd.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";"(.)x";"$1y";2) returns "axbycxd", the second match of "(.)x" (i.e. "bx") replaced with the captured group of one character (i.e. "b") followed by "y"." This is the case that exercises the documented "references to capture groups" in the Replacement parameter, and the $1 syntax is ICU's. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'axbycxd', got '#NAME?'
-
=ISNA(REGEX("abc","z")) on
Excel for the web returned
False, but the documented/expected
result is True.
Provenance
DERIVED, and the one case in this file that is not published: the Expression parameter's description states "If there is no match and Replacement is not given, #N/A is returned", and the Occurrence description repeats it. This is the only place in the batch where a LibreOffice page names a specific error value, so it is the only place an error value is asserted. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected True, got False
-
=REGEX("123456ABCDEF","[:digit:]","Z") on
Google Sheets returned
#NAME?, but the documented/expected
result is Z23456ABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z") returns "Z23456ABCDEF", where the first match of a digit is replaced by "Z"." This page is the best-documented in the whole batch -- five worked examples with printed results -- so five of the six cases here are published rather than derived. THE REGEX FLAVOUR IS PART OF THE FINDING AND THE PAGE STATES IT: "Expression: A text representing the regular expression, using ICU regular expressions." That is a different flavour from the PCRE2 that Microsoft's REGEXEXTRACT/REGEXREPLACE/REGEXTEST pages specify, which is why this corpus keeps LibreOffice's REGEX and Microsoft's REGEX* trio as separate functions rather than treating either as the other's alias. Note also that the bracket expression published here is "[:digit:]" -- a bracketed set of the six characters : d g i t, not the POSIX class [[:digit:]] -- which happens to match the digits in this input anyway; the value asserted is the one the page publishes for the expression the page publishes. STORAGE FORM, ESTABLISHED EMPIRICALLY IN BOTH DIRECTIONS BEFORE THIS FILE WAS RUN. A LibreOffice-only function has no OOXML name of its own -- the .xlsx format was frozen on Excel's function set -- so LibreOffice invents one, and this harness must write exactly the token LibreOffice's own .xlsx filter reads. Both directions were measured rather than assumed. IMPORT: every candidate spelling was written into a workbook by openpyxl (which caches no value, so the engine must evaluate from scratch) and round-tripped through `soffice --headless --convert-to xlsx` on all four pinned builds. EXPORT: the same formulas were fed to each build through its own formula parser and written back out to .xlsx, and the stored token was read out of the raw sheet XML. The token recorded for this function in harness/xlfn_map.py is the one both directions agree on across all four builds; the per-function note above says which it is. BATCH PROVENANCE (batch I, group C -- LibreOffice-only functions). This function has x == false AND g == false in docs/data/compat.json: NEITHER Microsoft NOR Google documents it, so this corpus makes no claim about either of those engines, nothing here is measured against their documentation, and the Excel column on the published page reads 'n/a (not an Excel function)' rather than a verdict. The authority is LibreOffice's own help, cited by full URL, by the date it was read (2026-08-31), and by the help version the page serves -- the URLs in this file are pinned to /25.8/ rather than /latest/ so the citation still means this text after the help site rolls forward, and /25.8/ is the help for the newest of the four engine builds the corpus executes. GOOGLE SHEETS: this batch builds the Sheets chunk whose ingest will record presence or absence in that engine. Until that ingest lands, the Sheets column on the published page reads 'Not yet' and nothing in this file claims anything about it. (Stated positively on purpose. scripts/check_honesty.py bans the blanket negative shape of this sentence outright -- it was once a true site-wide claim and is now false for more than 500 functions -- and that guard is worth keeping blunt, so this note carries the same per-function fact in a form the guard does not have to make an exception for.) LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'Z23456ABCDEF', got '#NAME?'
-
=REGEX("123456ABCDEF","[:digit:]","Z","g") on
Google Sheets returned
#NAME?, but the documented/expected
result is ZZZZZZABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z";"g") returns "ZZZZZZABCDEF", where all digits were replaced by "Z"." Matches the documented Flags parameter: "'g' replaces all matches of Expression in Text, not extracted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'ZZZZZZABCDEF', got '#NAME?'
-
=REGEX("123456ABCDEF","[126]","","g") on
Google Sheets returned
#NAME?, but the documented/expected
result is 345ABCDEF.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[126]";"";"g") returns "345ABCDEF", where any occurrence of "1", "2" or "6" is replaced by the empty string, thus deleted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected '345ABCDEF', got '#NAME?'
-
=REGEX("axbxcxd",".x",,2) on
Google Sheets returned
#NAME?, but the documented/expected
result is bx.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";".x";;2) returns "bx", the second match of ".x"." The empty third argument is the page's own -- Replacement omitted turns the call from a replace into an extract, per "Occurrence: ... Number to indicate which match of Expression in Text is to be extracted or replaced." It is written here exactly as published, empty argument included. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'bx', got '#NAME?'
-
=REGEX("axbxcxd","(.)x","$1y",2) on
Google Sheets returned
#NAME?, but the documented/expected
result is axbycxd.
Provenance
LIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";"(.)x";"$1y";2) returns "axbycxd", the second match of "(.)x" (i.e. "bx") replaced with the captured group of one character (i.e. "b") followed by "y"." This is the case that exercises the documented "references to capture groups" in the Replacement parameter, and the $1 syntax is ICU's. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected 'axbycxd', got '#NAME?'
-
=ISNA(REGEX("abc","z")) on
Google Sheets returned
False, but the documented/expected
result is True.
Provenance
DERIVED, and the one case in this file that is not published: the Expression parameter's description states "If there is no match and Replacement is not given, #N/A is returned", and the Occurrence description repeats it. This is the only place in the batch where a LibreOffice page names a specific error value, so it is the only place an error value is asserted. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html.; MISMATCH vs expected: expected True, got False
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 |
|---|---|---|---|---|
| =REGEX("123456ABCDEF","[:digit:]","Z") | LibreOffice's own published example: replace the first match | #NAME? | Z23456ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z") returns "Z23456ABCDEF", where the first match of a digit is replaced by "Z"." This page is the best-documented in the whole batch -- five worked examples with printed results -- so five of the six cases here are published rather than derived. THE REGEX FLAVOUR IS PART OF THE FINDING AND THE PAGE STATES IT: "Expression: A text representing the regular expression, using ICU regular expressions." That is a different flavour from the PCRE2 that Microsoft's REGEXEXTRACT/REGEXREPLACE/REGEXTEST pages specify, which is why this corpus keeps LibreOffice's REGEX and Microsoft's REGEX* trio as separate functions rather than treating either as the other's alias. Note also that the bracket expression published here is "[:digit:]" -- a bracketed set of the six characters : d g i t, not the POSIX class [[:digit:]] -- which happens to match the digits in this input anyway; the value asserted is the one the page publishes for the expression the page publishes. STORAGE FORM, ESTABLISHED EMPIRICALLY IN BOTH DIRECTIONS BEFORE THIS FILE WAS RUN. A LibreOffice-only function has no OOXML name of its own -- the .xlsx format was frozen on Excel's function set -- so LibreOffice invents one, and this harness must write exactly the token LibreOffice's own .xlsx filter reads. Both directions were measured rather than assumed. IMPORT: every candidate spelling was written into a workbook by openpyxl (which caches no value, so the engine must evaluate from scratch) and round-tripped through `soffice --headless --convert-to xlsx` on all four pinned builds. EXPORT: the same formulas were fed to each build through its own formula parser and written back out to .xlsx, and the stored token was read out of the raw sheet XML. The token recorded for this function in harness/xlfn_map.py is the one both directions agree on across all four builds; the per-function note above says which it is. BATCH PROVENANCE (batch I, group C -- LibreOffice-only functions). This function has x == false AND g == false in docs/data/compat.json: NEITHER Microsoft NOR Google documents it, so this corpus makes no claim about either of those engines, nothing here is measured against their documentation, and the Excel column on the published page reads 'n/a (not an Excel function)' rather than a verdict. The authority is LibreOffice's own help, cited by full URL, by the date it was read (2026-08-31), and by the help version the page serves -- the URLs in this file are pinned to /25.8/ rather than /latest/ so the citation still means this text after the help site rolls forward, and /25.8/ is the help for the newest of the four engine builds the corpus executes. GOOGLE SHEETS: this batch builds the Sheets chunk whose ingest will record presence or absence in that engine. Until that ingest lands, the Sheets column on the published page reads 'Not yet' and nothing in this file claims anything about it. (Stated positively on purpose. scripts/check_honesty.py bans the blanket negative shape of this sentence outright -- it was once a true site-wide claim and is now false for more than 500 functions -- and that guard is worth keeping blunt, so this note carries the same per-function fact in a form the guard does not have to make an exception for.) LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("123456ABCDEF","[:digit:]","Z","g") | LibreOffice's own published example: the g flag replaces every match | #NAME? | ZZZZZZABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z";"g") returns "ZZZZZZABCDEF", where all digits were replaced by "Z"." Matches the documented Flags parameter: "'g' replaces all matches of Expression in Text, not extracted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("123456ABCDEF","[126]","","g") | LibreOffice's own published example: an empty replacement deletes | #NAME? | 345ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[126]";"";"g") returns "345ABCDEF", where any occurrence of "1", "2" or "6" is replaced by the empty string, thus deleted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("axbxcxd",".x",,2) | LibreOffice's own published example: the Occurrence argument extracts | #NAME? | bxProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";".x";;2) returns "bx", the second match of ".x"." The empty third argument is the page's own -- Replacement omitted turns the call from a replace into an extract, per "Occurrence: ... Number to indicate which match of Expression in Text is to be extracted or replaced." It is written here exactly as published, empty argument included. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("axbxcxd","(.)x","$1y",2) | LibreOffice's own published example: a capture-group reference in the replacement | #NAME? | axbycxdProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";"(.)x";"$1y";2) returns "axbycxd", the second match of "(.)x" (i.e. "bx") replaced with the captured group of one character (i.e. "b") followed by "y"." This is the case that exercises the documented "references to capture groups" in the Replacement parameter, and the $1 syntax is ICU's. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =ISNA(REGEX("abc","z")) | The documented #N/A for a failed match with no replacement given | False | TrueProvenanceDERIVED, and the one case in this file that is not published: the Expression parameter's description states "If there is no match and Replacement is not given, #N/A is returned", and the Occurrence description repeats it. This is the only place in the batch where a LibreOffice page names a specific error value, so it is the only place an error value is asserted. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
Google Sheets (executed 2026-09-01 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 |
|---|---|---|---|---|
| =REGEX("123456ABCDEF","[:digit:]","Z") | LibreOffice's own published example: replace the first match | #NAME? | Z23456ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z") returns "Z23456ABCDEF", where the first match of a digit is replaced by "Z"." This page is the best-documented in the whole batch -- five worked examples with printed results -- so five of the six cases here are published rather than derived. THE REGEX FLAVOUR IS PART OF THE FINDING AND THE PAGE STATES IT: "Expression: A text representing the regular expression, using ICU regular expressions." That is a different flavour from the PCRE2 that Microsoft's REGEXEXTRACT/REGEXREPLACE/REGEXTEST pages specify, which is why this corpus keeps LibreOffice's REGEX and Microsoft's REGEX* trio as separate functions rather than treating either as the other's alias. Note also that the bracket expression published here is "[:digit:]" -- a bracketed set of the six characters : d g i t, not the POSIX class [[:digit:]] -- which happens to match the digits in this input anyway; the value asserted is the one the page publishes for the expression the page publishes. STORAGE FORM, ESTABLISHED EMPIRICALLY IN BOTH DIRECTIONS BEFORE THIS FILE WAS RUN. A LibreOffice-only function has no OOXML name of its own -- the .xlsx format was frozen on Excel's function set -- so LibreOffice invents one, and this harness must write exactly the token LibreOffice's own .xlsx filter reads. Both directions were measured rather than assumed. IMPORT: every candidate spelling was written into a workbook by openpyxl (which caches no value, so the engine must evaluate from scratch) and round-tripped through `soffice --headless --convert-to xlsx` on all four pinned builds. EXPORT: the same formulas were fed to each build through its own formula parser and written back out to .xlsx, and the stored token was read out of the raw sheet XML. The token recorded for this function in harness/xlfn_map.py is the one both directions agree on across all four builds; the per-function note above says which it is. BATCH PROVENANCE (batch I, group C -- LibreOffice-only functions). This function has x == false AND g == false in docs/data/compat.json: NEITHER Microsoft NOR Google documents it, so this corpus makes no claim about either of those engines, nothing here is measured against their documentation, and the Excel column on the published page reads 'n/a (not an Excel function)' rather than a verdict. The authority is LibreOffice's own help, cited by full URL, by the date it was read (2026-08-31), and by the help version the page serves -- the URLs in this file are pinned to /25.8/ rather than /latest/ so the citation still means this text after the help site rolls forward, and /25.8/ is the help for the newest of the four engine builds the corpus executes. GOOGLE SHEETS: this batch builds the Sheets chunk whose ingest will record presence or absence in that engine. Until that ingest lands, the Sheets column on the published page reads 'Not yet' and nothing in this file claims anything about it. (Stated positively on purpose. scripts/check_honesty.py bans the blanket negative shape of this sentence outright -- it was once a true site-wide claim and is now false for more than 500 functions -- and that guard is worth keeping blunt, so this note carries the same per-function fact in a form the guard does not have to make an exception for.) LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("123456ABCDEF","[:digit:]","Z","g") | LibreOffice's own published example: the g flag replaces every match | #NAME? | ZZZZZZABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z";"g") returns "ZZZZZZABCDEF", where all digits were replaced by "Z"." Matches the documented Flags parameter: "'g' replaces all matches of Expression in Text, not extracted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("123456ABCDEF","[126]","","g") | LibreOffice's own published example: an empty replacement deletes | #NAME? | 345ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[126]";"";"g") returns "345ABCDEF", where any occurrence of "1", "2" or "6" is replaced by the empty string, thus deleted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("axbxcxd",".x",,2) | LibreOffice's own published example: the Occurrence argument extracts | #NAME? | bxProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";".x";;2) returns "bx", the second match of ".x"." The empty third argument is the page's own -- Replacement omitted turns the call from a replace into an extract, per "Occurrence: ... Number to indicate which match of Expression in Text is to be extracted or replaced." It is written here exactly as published, empty argument included. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =REGEX("axbxcxd","(.)x","$1y",2) | LibreOffice's own published example: a capture-group reference in the replacement | #NAME? | axbycxdProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";"(.)x";"$1y";2) returns "axbycxd", the second match of "(.)x" (i.e. "bx") replaced with the captured group of one character (i.e. "b") followed by "y"." This is the case that exercises the documented "references to capture groups" in the Replacement parameter, and the $1 syntax is ICU's. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
| =ISNA(REGEX("abc","z")) | The documented #N/A for a failed match with no replacement given | False | TrueProvenanceDERIVED, and the one case in this file that is not published: the Expression parameter's description states "If there is no match and Replacement is not given, #N/A is returned", and the Occurrence description repeats it. This is the only place in the batch where a LibreOffice page names a specific error value, so it is the only place an error value is asserted. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Mismatch |
LibreOffice Calc 25.8.7.3 (tested 2026-09-01)
| Formula | Description | Result | Expected | Verdict |
|---|---|---|---|---|
| =REGEX("123456ABCDEF","[:digit:]","Z") | LibreOffice's own published example: replace the first match | Z23456ABCDEF | Z23456ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z") returns "Z23456ABCDEF", where the first match of a digit is replaced by "Z"." This page is the best-documented in the whole batch -- five worked examples with printed results -- so five of the six cases here are published rather than derived. THE REGEX FLAVOUR IS PART OF THE FINDING AND THE PAGE STATES IT: "Expression: A text representing the regular expression, using ICU regular expressions." That is a different flavour from the PCRE2 that Microsoft's REGEXEXTRACT/REGEXREPLACE/REGEXTEST pages specify, which is why this corpus keeps LibreOffice's REGEX and Microsoft's REGEX* trio as separate functions rather than treating either as the other's alias. Note also that the bracket expression published here is "[:digit:]" -- a bracketed set of the six characters : d g i t, not the POSIX class [[:digit:]] -- which happens to match the digits in this input anyway; the value asserted is the one the page publishes for the expression the page publishes. STORAGE FORM, ESTABLISHED EMPIRICALLY IN BOTH DIRECTIONS BEFORE THIS FILE WAS RUN. A LibreOffice-only function has no OOXML name of its own -- the .xlsx format was frozen on Excel's function set -- so LibreOffice invents one, and this harness must write exactly the token LibreOffice's own .xlsx filter reads. Both directions were measured rather than assumed. IMPORT: every candidate spelling was written into a workbook by openpyxl (which caches no value, so the engine must evaluate from scratch) and round-tripped through `soffice --headless --convert-to xlsx` on all four pinned builds. EXPORT: the same formulas were fed to each build through its own formula parser and written back out to .xlsx, and the stored token was read out of the raw sheet XML. The token recorded for this function in harness/xlfn_map.py is the one both directions agree on across all four builds; the per-function note above says which it is. BATCH PROVENANCE (batch I, group C -- LibreOffice-only functions). This function has x == false AND g == false in docs/data/compat.json: NEITHER Microsoft NOR Google documents it, so this corpus makes no claim about either of those engines, nothing here is measured against their documentation, and the Excel column on the published page reads 'n/a (not an Excel function)' rather than a verdict. The authority is LibreOffice's own help, cited by full URL, by the date it was read (2026-08-31), and by the help version the page serves -- the URLs in this file are pinned to /25.8/ rather than /latest/ so the citation still means this text after the help site rolls forward, and /25.8/ is the help for the newest of the four engine builds the corpus executes. GOOGLE SHEETS: this batch builds the Sheets chunk whose ingest will record presence or absence in that engine. Until that ingest lands, the Sheets column on the published page reads 'Not yet' and nothing in this file claims anything about it. (Stated positively on purpose. scripts/check_honesty.py bans the blanket negative shape of this sentence outright -- it was once a true site-wide claim and is now false for more than 500 functions -- and that guard is worth keeping blunt, so this note carries the same per-function fact in a form the guard does not have to make an exception for.) LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
| =REGEX("123456ABCDEF","[:digit:]","Z","g") | LibreOffice's own published example: the g flag replaces every match | ZZZZZZABCDEF | ZZZZZZABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[:digit:]";"Z";"g") returns "ZZZZZZABCDEF", where all digits were replaced by "Z"." Matches the documented Flags parameter: "'g' replaces all matches of Expression in Text, not extracted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
| =REGEX("123456ABCDEF","[126]","","g") | LibreOffice's own published example: an empty replacement deletes | 345ABCDEF | 345ABCDEFProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("123456ABCDEF";"[126]";"";"g") returns "345ABCDEF", where any occurrence of "1", "2" or "6" is replaced by the empty string, thus deleted." LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
| =REGEX("axbxcxd",".x",,2) | LibreOffice's own published example: the Occurrence argument extracts | bx | bxProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";".x";;2) returns "bx", the second match of ".x"." The empty third argument is the page's own -- Replacement omitted turns the call from a replace into an extract, per "Occurrence: ... Number to indicate which match of Expression in Text is to be extracted or replaced." It is written here exactly as published, empty argument included. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
| =REGEX("axbxcxd","(.)x","$1y",2) | LibreOffice's own published example: a capture-group reference in the replacement | axbycxd | axbycxdProvenanceLIBREOFFICE'S OWN PUBLISHED RESULT, quoted verbatim: "=REGEX("axbxcxd";"(.)x";"$1y";2) returns "axbycxd", the second match of "(.)x" (i.e. "bx") replaced with the captured group of one character (i.e. "b") followed by "y"." This is the case that exercises the documented "references to capture groups" in the Replacement parameter, and the $1 syntax is ICU's. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
| =ISNA(REGEX("abc","z")) | The documented #N/A for a failed match with no replacement given | True | TrueProvenanceDERIVED, and the one case in this file that is not published: the Expression parameter's description states "If there is no match and Replacement is not given, #N/A is returned", and the Occurrence description repeats it. This is the only place in the batch where a LibreOffice page names a specific error value, so it is the only place an error value is asserted. LibreOffice's REGEX help page, read live on 2026-08-31 at https://help.libreoffice.org/25.8/en-US/text/scalc/01/func_regex.html. |
Matched |
Docs & syntax
- LibreOffice Calc: official documentation
Where REGEX 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.