Text functions
REGEXREPLACE
Matches all 8 recorded answers
Recorded: 8 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | REGEXREPLACE |
| Bulgarian | REGEXREPLACE |
| Czech | REGEXNAHRADIT |
| Danish | REGEXERSTAT |
| German | REGEXREPLACE |
| Greek | REGEXREPLACE |
| English (Australia) | REGEXREPLACE |
| English (United Kingdom) | REGEXREPLACE |
| English (United States) | REGEXREPLACE |
| Spanish | REGEXREEMPLAZAR |
| Estonian | REGEXREPLACE |
| Finnish | REGEXKORVAA |
| French | REGEX.REMPLACER |
| Hebrew | REGEXREPLACE |
| Croatian | REGEXREPLACE |
| Hungarian | REGKIFCSERE |
| Indonesian | REGEXREPLACE |
| Italian | REGEXREPLACE |
| Japanese | REGEXREPLACE |
| Korean | REGEXREPLACE |
| Lithuanian | REGEXREPLACE |
| Latvian | REGEXREPLACE |
| Norwegian | REGEXREPLACE |
| Dutch | REGEXVERVANGEN |
| Polish | REGEXZASTĄP |
| Portuguese (Brazil) | REGEXREPLACE |
| Portuguese (Portugal) | REGEX.SUBSTITUIR |
| Romanian | REGEXREPLACE |
| Russian | РЕГЗАМЕНИТЬ |
| Slovak | REGEXREPLACE |
| Slovenian | REGEXREPLACE |
| Serbian (Latin) | REGEXREPLACE |
| Swedish | REGEXERSÄTT |
| Thai | REGEXREPLACE |
| Turkish | NORMİFADEDEĞİŞTİR |
| Ukrainian | REGEXREPLACE |
| Vietnamese | REGEXREPLACE |
| Chinese (Simplified) | REGEXREPLACE |
| Chinese (Hong Kong) | REGEXREPLACE |
| Chinese (Traditional) | REGEXREPLACE |
Names from Microsoft's support site.
What it does
REGEXREPLACE(text, pattern, replacement, [occurrence], [case_sensitivity])
REGEXREPLACE finds matches of a regular expression in a string and substitutes replacement text
for them, returning the rewritten string.
The operation is: scan text for non-overlapping matches of pattern from the left; for the
match or matches selected by the occurrence argument, splice replacement in place of the
matched substring; leave everything else untouched; return the result. The unmatched parts of the
string pass through verbatim, which is what distinguishes a replace from an extract.
The dialect is PCRE2, per the family statement on Microsoft's REGEXTEST page.
What the same replay does pin, as an upstream observation, is the selective form:
REGEXREPLACE("abc123def", "[a-z]+", "X", 2) -> abc123X — a positive occurrence of 2 rewriting
the second match and leaving the first alone.
Arguments
REGEXREPLACE(text, pattern, replacement, [occurrence], [case_sensitivity])
| Argument | Required | Meaning |
|---|---|---|
text | yes | The text to rewrite. |
pattern | yes | The regular expression identifying what to replace. |
replacement | yes | The text substituted for each selected match. |
occurrence | no | Which match to replace. Upstream records a positive n as replacing the n-th match; the omitted default is unresolved — see above. |
case_sensitivity | no | 0 case-sensitive, 1 case-insensitive, matching the family's polarity. |
Try it
Quirks
Result and edge cases
The return kind is Text.
- No match returns the input unchanged. This is the natural reading and is how every replace
function in common use behaves, but note that it differs from
REGEXEXTRACT, which returns#N/Aon no match. If your formula needs to know whether anything was replaced,REGEXREPLACEwill not tell you — pair it withREGEXTEST. - Zero-width matches need an advance rule. A pattern that can match the empty string, replaced globally, would otherwise loop or insert the replacement between every character. Which of those Excel does is unprobed.
- The result can grow past the text cap. Replacing a short pattern with a long replacement in a long string is the easiest way in the text family to exceed 32,767 code units. The cap and its two enforcement paths are described in the value universe.
- Non-text arguments coerce to text by the ordinary rules in coercion and lifting. The generated battery rows that pass a number in all three positions are coercion artefacts, not regex behaviour.
- Errors propagate ahead of matching.
- An empty referenced cell delivers
Empty, distinct from an omitted argument. - Array arguments are not asserted here.
Errors
Microsoft's page is the authority on documented error conditions; it was not retrievable while this entry was written, so this section states bases rather than quoting it.
| Error | Basis |
|---|---|
| any error value arriving in an argument | propagates, per the universal rule in the coercion chapter |
#VALUE! for a pattern the engine will not compile | expected; the exact rejected set is not established |
#VALUE! for an occurrence outside the admitted domain (0, negative, non-integer) | expected; unprobed |
#VALUE! if the result exceeds the text cap on the formula path | expected from the value-universe chapter; unprobed for this function |
How to implement
Notes for implementers
- Decide and document the default-occurrence question. It is the single most visible behaviour
of the function and the sources consulted here do not settle it. Do not copy a default from
another language's
replace. - Decide whether
replacementis a template or a literal, and be loud about it. If it is a template,$becomes a metacharacter and every user string containing a dollar sign is a latent bug; if it is literal, capture-group substitution is impossible and users will ask why. - Advance past zero-width matches or the global replace does not terminate.
- Splice, do not rebuild by repeated search. Repeatedly searching the partially rewritten string can match text that the replacement itself introduced — a classic and silent defect.
- The escape set is part of the contract. The upstream record's live-Excel comparison lists as
admitted, on the build it tested:
\d \D \w \W \s \S;\A \Z \z \b \B;\n \t \r \f \v \e \h; and the escaped literals\. \* \+ \? \[ \] \( \) \| \^ \$ \/ \\; and lists unknown letter escapes such as\q \k \m \g \p \c \x \y \j \oas rejected. Upstream observation on one Excel build, not a Handbook claim. - Check the result against the text cap and decide which failure you implement.
- Bound the match effort, or a pathological pattern hangs a recalculation.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
REGEXREPLACE · 1 lines · calc-func/src/catalogue/text_format.rs on GitHub18 regexreplace_fn "REGEXREPLACE" (3, 5) [V "text", V "pattern", V "replacement", V "occurrence", V "case_sensitivity"] |s, a, sv| { regexreplace(s, a) }
regexreplace · 34 lines · calc-func/src/catalogue/text_format.rs on GitHubfn regexreplace(site: &Site<'_>, a: &[CalcValue]) -> Step<CalcValue> {
let text = text_arg(site, a, 0)?;
let pattern = text_arg(site, a, 1)?;
let replacement = text_arg(site, a, 2)?.to_string_lossy();
if replacement.contains('$') || replacement.contains('\\') {
// Group references in the replacement are not modelled.
return Err(site.not_modelled(Some(2)));
}
let occurrence = if given(a, 3) { num(site, a, 3)?.trunc() } else { 0.0 };
let sensitive = case_sensitive(site, a, 4)?;
let (chars, found) = regex(site, &text, &pattern, sensitive, false)?;
let selected: Vec<(usize, usize)> = if occurrence == 0.0 {
found
} else if occurrence > 0.0 {
found.get(occurrence as usize - 1).copied().into_iter().collect()
} else {
let back = (-occurrence) as usize;
found
.len()
.checked_sub(back)
.and_then(|i| found.get(i).copied())
.into_iter()
.collect()
};
let mut out = String::new();
let mut cursor = 0;
for (start, end) in selected {
out.extend(chars[cursor..start].iter());
out.push_str(&replacement);
cursor = end;
}
out.extend(chars[cursor..].iter());
Ok(crate::catalogue::kit::text_value(&out))
}
Kernels shared with other functions
read_valuecatalogue/text_formatvaluecatalogue/text_formatprofilecatalogue/text_formatrenderedcatalogue/text_formattextcatalogue/text_formatgivencatalogue/text_formatbinary_flagcatalogue/text_formatcase_sensitivecatalogue/text_formatregexcatalogue/text_formatlow32decimalNatural::zerodecimalNatural::from_u64decimalNatural::pow10decimalNatural::normalizedecimalNatural::is_zerodecimalNatural::mul_add_smalldecimalNatural::times_pow10decimalNatural::times_pow5decimalNatural::times_pow2decimalExactDecimal::readdecimalExactDecimal::binarydecimalhas_invalid_exponentformat/datetimelooks_like_datetime_formatformat/datetimewithout_subsecondsformat/datetimerender_with_datetime_tokensformat/datetimetokenize_datetime_formatformat/datetimeelapsed_token_atformat/datetimeclassify_minute_tokensformat/datetimetoken_kindformat/datetimeis_time_neighborformat/datetimepush_literalformat/datetimerender_datetime_literalformat/datetimeformat_elapsedformat/datetimeTimeParts::from_serialformat/datetimemeasured_hostformatcurrency_literalformatdigitsformatfifteenformatsplitformatgroupedformatgeneralformatsignificantformatsectionsformatbracketformatis_conditionformatis_elapsedformatcondition_holdsformatcondition_offormatstrip_tokensformatchooseformatitemsformatnumericformatliteral_textformatinteger_partformatfraction_partformatscientificformatfraction_codeformatFractionCode::renderformatmixed_fraction_under_space_groupingformatconvergentformattext_declared_date_localeformattextformattext_of_textformatmonth_nameformat/namesweekday_nameformat/nameslocale_namesformat/namesLocaleId::from_bcp47_language_taglocaleLocaleId::from_excel_lcidlocaleshort_date_orderlocaleshort_date_patternlocalecurrency_placementlocalecurrency_spacinglocalecurrency_negative_patternlocaleformat_profilelocaledays_from_civillocalecivil_from_dayslocaleymd_from_excel_seriallocaledecimalnumber_textfirst_precisionnumber_textnear_tienumber_textfirst_roundingnumber_textroundednumber_textincrementnumber_textasciinumber_textdays_from_civilported/date_kernelscivil_from_daysported/date_kernelsserial_unbounded_1900ported/date_kernelsymd_1900ported/date_kernelsis_leapported/date_kernelsdays_in_monthported/date_kernelswhole_serialported/date_kernelswholeported/date_kernelsweekday_sunday_one_basedported/date_kernelsremap_weekdayported/date_kernelsweekday_ofported/date_kernelsweekdayported/date_kernelstextported/text_kernelstext_from_strported/text_kernelsdate_integer_floorported/text_kernelspush_singleton_or_originalported/text_kernelspush_upperported/text_kernelsis_well_formedported/text_kernelsupperported/text_kernelsis_word_charported/text_morechars_equalported/text_morerange_containsported/text_morefolded_rangeported/text_moreclass_item_matchesported/text_moreis_word_boundaryported/text_morezero_width_atom_matchesported/text_moreatom_consumes_inputported/text_moreconsuming_atom_matchesported/text_morematch_atom_onceported/text_morematch_tokens_fromported/text_morefind_first_match_fromported/text_morefind_all_matchesported/text_moreescaped_literal_charported/text_moreparse_escape_atomported/text_moreparse_class_pieceported/text_moreparse_char_classported/text_moreparse_regex_patternported/text_moreregex_matchesported/text_moremeasured_host_readervalue_textmeasured_spacevalue_textreadvalue_textnumbervalue_textdecimalvalue_textfractionvalue_texttokensvalue_textmonth_namedvalue_texttime_atvalue_textfull_yearvalue_textvalid_dayvalue_textthis_yearvalue_textserial_1900value_textdate_ofvalue_textdate_timevalue_text
Argument and result plumbing
failcatalogue/kitnumcatalogue/kittext_argcatalogue/kittext_valuecatalogue/kitnumbercoerce
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
REGEXTEST— the predicate. Use it to find out whether a replace would do anything.REGEXEXTRACT— the extractor. Same engine; returns the match instead of rewriting around it.SUBSTITUTE— the direct predecessor and still the right tool for literal text. It takes aninstance_numin the same spirit asoccurrence, and upstream records its rules for the current baseline: an emptyold_textleaves the source unchanged, andinstance_num < 1is#VALUE!.SUBSTITUTEis not superseded and is clearer for any non-pattern replacement.REPLACE— positional replacement by start and length; a different job entirely despite the near-identical name. Readers confuseREPLACEandREGEXREPLACEconstantly; the first takes character positions, the second takes a pattern.TRIM— worth mentioning becauseREGEXREPLACE(x, "\s+", " ")is the obvious "trim with a wider whitespace set" idiom, and is the standard workaround forTRIMnot touching non-breaking spaces. Whether Excel's\sincludes the non-breaking space is itself unprobed.TEXTJOIN,TEXTSPLIT— the delimiter tools, usually a better fit than a regex when the structure really is a separator.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents