How Do Substrings Work in XSLT regex?
In XSLT 2.0 and later versions, text analysis and tokenization are
significantly simplified through the
<xsl:analyze-string> instruction. This element works
by evaluating an input string against a regular expression pattern,
automatically splitting the text into portions that match the pattern
and portions that do not. By nesting
<xsl:matching-substring> and
<xsl:non-matching-substring> child elements inside,
developers can conditionally transform, wrap, format, or discard
specific text segments based on pattern recognition without writing
complex recursive templates.
Understanding the
<xsl:analyze-string> Context
The <xsl:analyze-string> element takes two primary
attributes: select, which defines the input string or XPath
expression, and regex, which specifies the regular
expression pattern to test against. Optional flags, such as
flags="i" for case-insensitivity or flags="m"
for multiline mode, can also be provided.
During execution, the processor scans the input string sequentially from left to right. Every piece of the string is categorized into one of two states:
- Substrings that conform to the regular expression.
- Substrings that lie between, before, or after the matching patterns.
The Role of
<xsl:matching-substring>
Whenever the XSLT processor encounters a segment of the string that
matches the pattern defined in the regex attribute, it
executes the template instructions contained within
<xsl:matching-substring>.
Inside this block, the context item (.) becomes a string
representing the exact matched text. Additionally, developers can use
the regex-group(N) function to extract specific captured
groups defined by parentheses in the regular expression.
<xsl:analyze-string select="description" regex="\[(.*?)\]">
<xsl:matching-substring>
<span class="bracketed-term">
<xsl:value-of select="regex-group(1)"/>
</span>
</xsl:matching-substring>
</xsl:analyze-string>In this scenario, text enclosed in square brackets is wrapped in HTML
<span> tags, while stripping out the outer bracket
characters using regex-group(1).
The Role of
<xsl:non-matching-substring>
Segments of the input string that do not satisfy the regex pattern
are processed by <xsl:non-matching-substring>. Within
this block, the context item (.) represents the
non-matching text slice.
This element is useful for preserving surrounding text, applying default escaping, or transforming plain text while leaving regex matches to be formatted separately:
<xsl:analyze-string select="content" 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>In this example, URLs are converted into active hyperlinks, while all standard text between the URLs is preserved unchanged.
Key Rules and Best Practices
- Order of Execution: The processor processes the
string in strict document order. If an input string starts with
non-matching text,
<xsl:non-matching-substring>runs first, followed by<xsl:matching-substring>when a match is found. - Optional Elements: Neither child element is
strictly mandatory. If
<xsl:matching-substring>is omitted, matching text is skipped. If<xsl:non-matching-substring>is omitted, non-matching text is discarded. - Avoid Zero-Length Matches: The regular expression
provided to
regexmust not match a zero-length string (such asa*on an empty sequence). Doing so triggers a dynamic errorXTDE1150.