XSLT Reference
replace()
Replaces all substrings of a string that match a regular expression with a replacement string.
replace(string, pattern, replacement, flags?)Description
replace() searches the input string for all occurrences of the regular expression pattern and substitutes each match with the replacement string. Unlike translate() (which works character-by-character), replace() operates on substrings and patterns, making it suitable for complex string transformations.
The replacement string may include back-references to captured groups using $1, $2, etc., where $0 refers to the entire matched substring. Dollar signs that are not back-references must be escaped as \$.
The function uses XPath regex syntax (a subset of XML Schema regex), which is similar to Java/Perl regex but does not support lookaheads or backreferences in the pattern itself.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
string | xs:string | Yes | The input string to perform replacements on. |
pattern | xs:string | Yes | Regular expression pattern matching the substrings to replace. |
replacement | xs:string | Yes | Replacement string; may use $0, $1, etc. for captured groups. |
flags | xs:string | No | Regex flags: i (case-insensitive), m (multiline), s (dot-all), x (extended). |
Return value
xs:string — the input string with all matches of pattern replaced by replacement.
Examples
Remove unwanted characters
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<prices>
<price>$1,299.00</price>
<price>$849.50</price>
</prices>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/prices">
<numbers>
<xsl:for-each select="price">
<!-- Remove $ and comma to get a plain number -->
<number><xsl:value-of select="replace(., '[\$,]', '')"/></number>
</xsl:for-each>
</numbers>
</xsl:template>
</xsl:stylesheet>
Output:
<numbers>
<number>1299.00</number>
<number>849.50</number>
</numbers>
Reformat a date using back-references
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<events>
<event date="2026-04-18">Conference</event>
<event date="2026-05-01">Workshop</event>
</events>
Stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/events">
<events>
<xsl:for-each select="event">
<!-- Reformat YYYY-MM-DD to DD/MM/YYYY -->
<event date="{replace(@date, '^(\d{{4}})-(\d{{2}})-(\d{{2}})$', '$3/$2/$1')}">
<xsl:value-of select="."/>
</event>
</xsl:for-each>
</events>
</xsl:template>
</xsl:stylesheet>
Output:
<events>
<event date="18/04/2026">Conference</event>
<event date="01/05/2026">Workshop</event>
</events>
Note: curly braces inside attribute value templates must be doubled: {{ and }}.
Collapse multiple spaces
<xsl:value-of select="replace(normalize-space(description), '\s+', ' ')"/>
Notes
replace()replaces all occurrences, not just the first. There is noreplaceFirst()equivalent in XPath.- To escape a literal
$in the replacement string, write\$. - The pattern cannot match an empty string; if the pattern can match zero characters Saxon raises a dynamic error.
- For simple character substitution,
translate()(XSLT 1.0) is simpler and more efficient. Usereplace()when you need pattern matching or back-references. - Inside attribute value templates, curly braces within the regex (e.g.,
\d{4}) must be doubled:\d{{4}}.