是否有可能从xsl:analyze-string中的重复正则表达式组中捕获值?

时间:2013-05-23 21:58:13

标签: regex xslt

我想做这样的事情:

<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>

=&GT;

<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
<letter>D</letter>

但似乎不可能,因为xsl:analyze-string只保留组中捕获的最后一个值,因此实际输出只是:

<letter>D</letter>    

一般问题是处理可能出现在未知订单中的已知值。

1 个答案:

答案 0 :(得分:4)

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>

=&GT;

<letter>A</letter>
<letter>B</letter>
<letter>C</letter>
<letter>D</letter>

但是,如果表达式的某些部分是严格排序的,而某些部分则不是,则会变得更加复杂。例如,假设有两个无序的组本身是有序的:

(1|2|3|4)+(A|B|C|D)+

将此正则表达式重写为(1|2|3|4)|(A|B|C|D)仍然可以获得结果(使用输入21CB):

<number>2</number>
<number>1</number>
<letter>C</letter>
<letter>B</letter>

但重写的正则表达式也匹配AB121A3C等,其中没有一个与原始表达式匹配。如果有人有更好的解决方案,我会很感兴趣。理想的解决方案是保留重复组的先前捕获,例如在.NET中。