3

我想做这样的事情:

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

=>

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

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

<letter>D</letter>    

一般问题是处理可能以未知顺序出现的已知值。

4

1 回答 1

5

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>

=>

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

但是重写后的正则表达式也会匹配AB12,1A3C等,它们都不匹配原始表达式。如果有人对此有更好的解决方案,我会非常感兴趣。理想的解决方案是保留以前捕获的重复组,例如在 .NET 中。

于 2013-05-23T21:58:13.077 回答