Replace
Replaces all occurrences of a substring with a new value. Runtime-proven on a live Marketing Cloud Engagement CloudPage — including matching that ignores case and a single-pass scan that never revisits text it just inserted.
Syntax
Replace(sourceString, searchSubstring[, replacementSubstring]) → string
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sourceString |
string | number | Yes | String to search in |
searchSubstring |
string | number | Yes | Text to look for |
replacementSubstring |
string | number | No | Text to put in its place; omit it to delete the match |
Example
%%[
VAR @greeting
SET @greeting = Replace("Hello World", "World", "There")
]%%
Greeting: %%=v(@greeting)=%%
Renders Greeting: Hello There.
The everyday use is flattening a delimited value for display, which relies on every occurrence being replaced rather than just the first:
%%[
VAR @tags, @readable
SET @tags = "one,two,three"
SET @readable = Replace(@tags, ",", " / ")
]%%
Interests: %%=v(@readable)=%%
That renders Interests: one / two / three.
Casing is not part of the match — see below before using this to swap a brand or product name.
Return value
string — the source with every match rewritten.
A source with no match comes back unchanged, and an empty source returns an empty string. The returned text is otherwise an open domain, so there is no closed set of values to test for.
Behaviour
Every occurrence is replaced. Replace("one,two,three", ",", " / ") rewrites both commas and gives one / two / three. A search string equal to the whole source works too: Replace("abc", "abc", "xyz") gives xyz.
No match leaves the source untouched. Searching for text that is absent returns the source verbatim, as does a search string longer than the source — neither is an error.
Omitting the third argument deletes the match. Replace("abc", "b") gives ac, so removing a fragment needs no empty-string placeholder. Passing an explicit empty string does the same: Replace("a-b-c", "-", "") gives abc.
An empty search string is a no-op. Replace("abc", "", "X") returns abc rather than interleaving X between the characters, and an empty source returns an empty string.
Numbers are accepted in all three positions and handled as their text form. Replacing the digit 0 with 9 inside the numeric literal 101101 gives 191191, a numeric search value matches inside a string, and a numeric replacement is inserted as its digits. Booleans are not usable in any position: a boolean source renders an empty string, and a boolean search value or replacement contributes nothing at all.
Replacement text is inserted verbatim, including non-ASCII. In a source built as caf + Char(233) + " time", which measures 9, the accented letter is replaceable by a plain e, and inserting Char(233) back into an ASCII source produces the accented letter — confirmed by dumping the code points rather than reading the console.
Casing is ignored, and the source is scanned once
| Call | Renders |
|---|---|
Replace("Hello World", "WORLD", "There") |
Hello There |
Replace("Hello World", "hELLO", "Howdy") |
Howdy World |
Replace("Cat cat CAT", "cat", "dog") |
dog dog dog |
Replace("aaa", "aa", "a") |
aa |
Replace("cat", "cat", "cat dog") |
cat dog |
Matching ignores case, so a lowercase search string rewrites capitalised and all-caps text alike — the same way IndexOf locates text. There is no case-sensitive variant, so a value whose casing carries meaning cannot be swapped selectively here.
The scan runs once over the source. Replacing aa with a inside aaa leaves aa, because the pair the replacement helped form is never revisited — this is not a normalising sweep. The same property makes a self-referential replacement safe: text you insert is never re-matched, so Replace("cat", "cat", "cat dog") terminates instead of looping.
Catalogued on Differs from official docs. The docs are silent on the casing, the optional argument and the scan order rather than wrong about them, so the entry is not flagged as contradicting them.
Show test script
%%[
VAR @b
SET @b = RequestParameter("b")
/* documented forms plus the accepted argument types */
IF @b == "safe" THEN
OutputLine(Concat("BASIC=[", Replace("Hello World", "World", "There"), "]"))
OutputLine(Concat("ALLOCC=[", Replace("one,two,three", ",", " / "), "]"))
OutputLine(Concat("WHOLE=[", Replace("abc", "abc", "xyz"), "]"))
OutputLine(Concat("MISSING=[", Replace("Hello World", "zzz", "!"), "]"))
OutputLine(Concat("LONGER=[", Replace("ab", "abcdef", "z"), "]"))
OutputLine(Concat("REMOVE=[", Replace("a-b-c", "-", ""), "]"))
OutputLine(Concat("EMPTYSRC=[", Replace("", "x", "y"), "]"))
OutputLine(Concat("NUMSRC=[", Replace(101101, "0", "9"), "]"))
OutputLine(Concat("NUMNEEDLE=[", Replace("a1b1c", 1, "-"), "]"))
OutputLine(Concat("NUMREPL=[", Replace("a-b", "-", 7), "]"))
OutputLine(Concat("BOOLSRC=[", Replace(true, "ru", "X"), "]"))
OutputLine(Concat("BOOLNEEDLE=[", Replace("is true here", true, "X"), "]"))
OutputLine(Concat("BOOLREPL=[", Replace("a-b", "-", true), "]"))
ENDIF
/* matching ignores case */
IF @b == "case" THEN
OutputLine(Concat("UPPERNEEDLE=[", Replace("Hello World", "WORLD", "There"), "]"))
OutputLine(Concat("LOWERNEEDLE=[", Replace("Hello World", "world", "There"), "]"))
OutputLine(Concat("MIXEDNEEDLE=[", Replace("Hello World", "hELLO", "Howdy"), "]"))
OutputLine(Concat("MULTICASE=[", Replace("Cat cat CAT", "cat", "dog"), "]"))
ENDIF
/* the two-argument form, the single-pass scan, and the empty search string */
IF @b == "shape" THEN
OutputLine(Concat("DROP=[", Replace("abc", "b"), "]"))
OutputLine(Concat("RECURSE=[", Replace("aaa", "aa", "a"), "]"))
OutputLine(Concat("SELFREF=[", Replace("cat", "cat", "cat dog"), "]"))
OutputLine(Concat("EMPTYNEEDLE=[", Replace("abc", "", "X"), "]"))
OutputLine(Concat("BOTHEMPTY=[", Replace("abc", "", ""), "]"))
ENDIF
/* non-ASCII text survives in both directions */
IF @b == "unicode" THEN
VAR @u
SET @u = Concat("caf", Char(233), " time")
OutputLine(Concat("UNILEN=[", Length(@u), "]"))
OutputLine(Concat("UNIREPL=[", Replace(@u, Char(233), "e"), "]"))
OutputLine(Concat("UNIINTO=[", Replace("cafe time", "e t", Concat(Char(233), " T")), "]"))
ENDIF
/* every branch below aborts the page: the start marker never renders */
IF @b == "a0" THEN
OutputLine(Concat("--- a0 start ---"))
OutputLine(Concat("A0=[", Replace(), "]"))
ENDIF
IF @b == "a1" THEN
OutputLine(Concat("--- a1 start ---"))
OutputLine(Concat("A1=[", Replace("abc"), "]"))
ENDIF
IF @b == "a4" THEN
OutputLine(Concat("--- a4 start ---"))
OutputLine(Concat("A4=[", Replace("abc", "b", "z", "extra"), "]"))
ENDIF
]%%
OutputLine given a bare string literal renders an empty line. Wrap the argument in Concat() or your start and done markers vanish silently — which looks exactly like the function failing.
When a case involves non-ASCII text, print the source alongside the result and check the code points. A terminal that mangles one accented letter will make a correct replacement look broken.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | Yes, from API 67.0 |
See also
- Differs from official docs — the casing and single-pass findings in full
IndexOf— finds the text instead of rewriting it, and matches case the same waySubstring— takes a portion of a string by position- Official reference · ampscript.guide