我想做这样的事情:
<xsl:analyze-string select="'ABCD'" regex="(A|B|C|D)+">
<xsl:matching-substring>
<xsl:for-each select="regex-group(1)">
<letter><xsl:value-of select="." /></letter>
</xsl:for-each>
</xsl:matching-substring>
</xsl:analyze-string>
Run Code Online (Sandbox Code Playgroud)
=>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
<letter>D</letter>
Run Code Online (Sandbox Code Playgroud)
但这似乎不可能,因为xsl:analyze-string只保留组中捕获的最后一个值,因此实际输出只是:
<letter>D</letter>
Run Code Online (Sandbox Code Playgroud)
一般问题是处理可能以未知顺序出现的已知值。
xsl:analyze-string将在一个字符串中自动重复和匹配多次。如果您重写表达式以匹配子字符串 - 而不是使用锚点和/或显式重复组一次匹配整个字符串 - 您可以获得正确的输出:
<xsl:analyze-string select="'ABCD'" regex="(A|B|C|D)">
<xsl:matching-substring>
<letter><xsl:value-of select="regex-group(1)" /></letter>
</xsl:matching-substring>
</xsl:analyze-string>
Run Code Online (Sandbox Code Playgroud)
=>
<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
<letter>D</letter>
Run Code Online (Sandbox Code Playgroud)
但是,如果表达式的某些部分是严格排序的,而有些则不是,这会变得更加复杂。例如,假设有两个无序组本身是有序的:
(1|2|3|4)+(A|B|C|D)+
Run Code Online (Sandbox Code Playgroud)
重写这个正则表达式(1|2|3|4)|(A|B|C|D)仍然可以得到(用作输入21CB)的结果:
<number>2</number>
<number>1</number>
<letter>C</letter>
<letter>B</letter>
Run Code Online (Sandbox Code Playgroud)
但是重写的正则表达式也会匹配AB12、1A3C等,这些都不匹配原始表达式。如果有人对此有更好的解决方案,我会非常感兴趣。理想的解决方案是保留重复组的先前捕获,例如在 .NET 中。