2

ネストされたグループをキャプチャする正規表現があり、それらのグループと相関するネストされた XML を出力したいと考えていますfn:analyze-string。簡単な例を次に示します。

正規表現

((Luckenbach|Houston|Little Rock),\s(TX|AK))

入力

Let's go to Luckenbach, TX with Waylon and Willie and the boys.

望ましい出力

<s:analyze-string-result xmlns:s="http://www.w3.org/2009/xpath-functions/analyze-string">
    <s:non-match>Let's go to </s:non-match>
    <s:match>
        <s:group nr="1">
            <s:group nr="2">Luckenbach</s:group>, <s:group nr="3">TX</s:group
        </s:group>
    </s:match>
    <s:non-match> with Waylon and Willie and the boys.</s:non-match>
</s:analyze-string-result>

regex-group()問題は、値を再帰的に処理xsl:analyze-stringするxsl:matching-substring(または xQuery fn:analyze-string() のように XML としてアクセスする)方法がないように見えることです。

ソリューションは、複数レベルのネストされたキャプチャ グループを持つ多くの正規表現で動作するように十分に汎用的である必要があります。

4

1 に答える 1

2

以下は、コンテキスト ノードにサンプル テキストが含まれている場合に、目的の出力を生成します。

    <snip>
        <xsl:analyze-string 
                select="." 
                regex="((Luckenbach|Houston|Little Rock),\s(TX|AK))">
            <xsl:matching-substring>
                <location>
                    <city><xsl:value-of select="regex-group(2)"/></city>
                    <xsl:text>, </xsl:text>
                    <state><xsl:value-of select="regex-group(3)"/></state>
                </location>                       
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>    
    </snip>

REGEX が一致した場合にのみ生成する<snip>場合は、REGEX とグループの処理をわずかに調整できます。

        <xsl:analyze-string 
                select="." 
                regex="((.*)((Luckenbach|Houston|Little Rock),\s(TX|AK))(.*))">
            <xsl:matching-substring>
                <snip>
                    <xsl:value-of select="regex-group(2)"/>
                    <location>
                        <city><xsl:value-of select="regex-group(4)"/></city>
                        <xsl:text>, </xsl:text>
                        <state><xsl:value-of select="regex-group(5)"/></state>
                    </location>
                    <xsl:value-of select="regex-group(6)"/>
                </snip>   
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string> 

XQuery 関数analyze-string()の動作を再現したい場合は、独自のカスタム関数を定義できます。

<xsl:function name="my:analyze-string" as="item()*" xmlns:my="http://stackoverflow.com/questions/13187307/output-nested-regex-groups-as-nested-xml-using-xslanalyze-string">
    <xsl:param name="val" />

    <analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions">   
        <xsl:analyze-string select="$val" regex="((.*)((Luckenbach|Houston|Little Rock),\s(TX|AK))(.*))">
            <xsl:matching-substring>
                <xsl:for-each select="1 to 6">
                    <xsl:if test="regex-group(.)">
                        <match>
                            <group  nr="{.}">
                                <xsl:value-of select="regex-group(.)"/>
                            </group>
                        </match>
                    </xsl:if>
                </xsl:for-each>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <non-match>
                    <xsl:value-of select="."/>
                </non-match> 
            </xsl:non-matching-substring>
        </xsl:analyze-string>    
    </analyze-string-result>   
</xsl:function>

このように呼び出されると:

 <xsl:variable name="value" 
      select='"Let&apos;s go to Luckenbach, TX with Waylon and Willie and the boys."'/>
 <xsl:copy-of select="my:analyze-string($value)"
    xmlns:my="http://stackoverflow.com/questions/13187307/output-nested-regex-groups-as-nested-xml-using-xslanalyze-string"/>  

次の出力が生成されます。

<analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"
                       xmlns:my="http://stackoverflow.com/questions/13187307/output-nested-regex-groups-as-nested-xml-using-xslanalyze-string">
   <match>
      <group nr="1">Let's go to Luckenbach, TX with Waylon and Willie and the boys.</group>
   </match>
   <match>
      <group nr="2">Let's go to </group>
   </match>
   <match>
      <group nr="3">Luckenbach, TX</group>
   </match>
   <match>
      <group nr="4">Luckenbach</group>
   </match>
   <match>
      <group nr="5">TX</group>
   </match>
   <match>
      <group nr="6"> with Waylon and Willie and the boys.</group>
   </match>
</analyze-string-result>
于 2012-11-02T00:50:59.940 に答える