您可以通过更改正则表达式的语法来使其更容易一些,使用<g> </g>
分组而不是()
(可能但很烦人不这样做,而是分析正则表达式并确定组)
一旦你有了组结构,你就可以生成正常的正则表达式,()
用来传递xsl:analyze-function
添加额外的组,这样每个文本运行都会被分组,以后可以用regex-group()
.
没有经过广泛测试,因此可能存在错误,但类似这样,它似乎适用于您的示例。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="data:,f"
exclude-result-prefixes="xs"
>
<xsl:output omit-xml-declaration="yes"/>
<xsl:function name="f:analyze-string">
<xsl:param name="s"/>
<xsl:param name="r"/>
<xsl:variable name="rr">
<xsl:apply-templates mode="a-s" select="$r"/>
</xsl:variable>
<xsl:text> </xsl:text>
<f:analyze-string-result>
<xsl:text> </xsl:text>
<xsl:analyze-string select="$s" regex="{$rr}">
<xsl:matching-substring>
<f:match>
<xsl:variable name="m" select="."/>
<xsl:apply-templates mode="g" select="$r"/>
</f:match>
<xsl:text> </xsl:text>
</xsl:matching-substring>
<xsl:non-matching-substring>
<f:non-match>
<xsl:value-of select="."/>
</f:non-match>
</xsl:non-matching-substring>
</xsl:analyze-string>
<xsl:text> </xsl:text>
</f:analyze-string-result>
<xsl:text> </xsl:text>
</xsl:function>
<xsl:template mode="a-s" match="g">
<xsl:text>(</xsl:text>
<xsl:apply-templates mode="a-s"/>
<xsl:text>)</xsl:text>
</xsl:template>
<xsl:template mode="a-s" match="text()[../g]">
<xsl:text>(</xsl:text>
<xsl:value-of select="."/>
<xsl:text>)</xsl:text>
</xsl:template>
<xsl:template mode="g" match="g">
<f:group>
<xsl:attribute name="nr">
<xsl:number level="any"/>
</xsl:attribute>
<xsl:apply-templates mode="g"/>
</f:group>
</xsl:template>
<xsl:template mode="g" match="text()">
<xsl:variable name="n">
<xsl:number count="g|text()[../g]" level="any"/>
</xsl:variable>
<xsl:value-of select="regex-group(xs:integer($n))"/>
</xsl:template>
<xsl:template name="main">
<!-- regex="^a((b(c))d)(efg)$" -->
<xsl:variable name="r">a<g><g>b<g>c</g></g>d</g><g>efg</g>$</xsl:variable>
<xsl:sequence select="f:analyze-string('abcdefg',$r)"/>
<!-- regex="^((a(bc)d)(.*))$ -->
<xsl:variable name="r"><g><g>a<g>bc</g>d</g><g>.*</g></g>$</xsl:variable>
<xsl:sequence select="f:analyze-string('abcdefg',$r)"/>
<!-- regex="^(((a)(b)(cde)(.*)))$" -->
<xsl:variable name="r"><g><g><g>a</g><g>b</g><g>cde</g><g>.*</g></g></g>$</xsl:variable>
<xsl:sequence select="f:analyze-string('abcdefg',$r)"/>
</xsl:template>
</xsl:stylesheet>
生产
$ saxon9 -it main analyse.xsl
<f:analyze-string-result xmlns:f="data:,f">
<f:match>a<f:group nr="1"><f:group nr="2">b<f:group nr="3">c</f:group></f:group>d</f:group><f:group nr="4">efg</f:group></f:match>
</f:analyze-string-result>
<f:analyze-string-result xmlns:f="data:,f">
<f:match><f:group nr="1"><f:group nr="2">a<f:group nr="3">bc</f:group>d</f:group><f:group nr="4">efg</f:group></f:group></f:match>
</f:analyze-string-result>
<f:analyze-string-result xmlns:f="data:,f">
<f:match><f:group nr="1"><f:group nr="2"><f:group nr="3">a</f:group><f:group nr="4">b</f:group><f:group nr="5">cde</f:group><f:group nr="6">fg</f:group></f:group></f:group></f:match>
</f:analyze-string-result>