XSLT Reference
xsl:analyze-string
Processes a string against a regular expression, separating matching and non-matching substrings for independent handling.
<xsl:analyze-string select="string" regex="pattern" flags="flags">Description
xsl:analyze-string scans a string for all occurrences of a regular expression and divides the string into alternating matching and non-matching substrings. For each portion, it invokes the appropriate child element:
xsl:matching-substring— processes each matched portion.xsl:non-matching-substring— processes each unmatched portion between matches.
Inside xsl:matching-substring, the regex-group() function returns captured groups from the match. The instruction processes the full string from left to right, emitting output for every segment in order.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
select | XPath expression | Yes | The string to analyze. |
regex | xs:string (AVT) | Yes | The regular expression pattern. |
flags | xs:string (AVT) | No | Flag characters: i (case-insensitive), m (multiline), s (dot-all), x (extended). |
Child elements (at least one is required):
| Child | Description |
|---|---|
xsl:matching-substring | Template for matched portions. |
xsl:non-matching-substring | Template for non-matched portions. |
xsl:fallback | Fallback for processors that do not support the instruction. |
Return value
A sequence of nodes and/or atomic values produced by the child templates, one per substring segment.
Examples
Marking up URLs in plain text
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<comments>
<comment>Visit https://example.com for details or http://docs.example.org/api.</comment>
</comments>
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="html" indent="yes"/>
<xsl:template match="/comments">
<div>
<xsl:apply-templates select="comment"/>
</div>
</xsl:template>
<xsl:template match="comment">
<p>
<xsl:analyze-string select="." regex="https?://[^\s]+">
<xsl:matching-substring>
<a href="{.}"><xsl:value-of select="."/></a>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</p>
</xsl:template>
</xsl:stylesheet>
Output:
<div>
<p>Visit <a href="https://example.com">https://example.com</a> for details or
<a href="http://docs.example.org/api">http://docs.example.org/api</a>.</p>
</div>
Parsing dates with capture groups
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<events>
<event>Conference on 2026-04-18 in Berlin</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">
<parsed>
<xsl:for-each select="event">
<xsl:analyze-string select="." regex="(\d{{4}})-(\d{{2}})-(\d{{2}})">
<xsl:matching-substring>
<date year="{regex-group(1)}" month="{regex-group(2)}" day="{regex-group(3)}"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</parsed>
</xsl:template>
</xsl:stylesheet>
Output:
<parsed>
<date year="2026" month="04" day="18"/>
</parsed>
Notes
- Inside attribute value templates, curly braces in the
regexmust be doubled:\d{{4}}to match\d{4}. - Both
xsl:matching-substringandxsl:non-matching-substringare optional. Omitting one effectively discards those segments. regex-group(0)returns the entire matched string;regex-group(n)returns the nth capture group.- The instruction iterates all non-overlapping matches from left to right. If no match is found, the entire string is processed as a single non-matching substring.
- XPath regex syntax is used (XML Schema flavor), which does not support lookahead or backreferences.