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:

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