Regex 如何在XSLT中每三个大写字母后添加零宽度空格?

Regex 如何在XSLT中每三个大写字母后添加零宽度空格?,regex,xslt-2.0,Regex,Xslt 2.0,我想在XSLT中每三个大写字母后添加零宽度空格。 在这里,我想选择文档中的所有文本节点,并在这些文本节点中过滤大写单词 我的XML示例代码是: <doc> <front> <lable>this is a TEST TEXT</lable> <para>This is a TEST TEXT with UPPER and Lower</para> </front>

我想在XSLT中每三个大写字母后添加零宽度空格。 在这里,我想选择文档中的所有文本节点,并在这些文本节点中过滤大写单词

我的XML示例代码是:

<doc>
    <front>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </front>
    <middle>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </middle>
    <back>
        <lable>This is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </back>
</doc>

这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
我编写的XSLT是:

<xsl:template match="*/text()" priority="100">
        <xsl:analyze-string select="." regex="^[A-Z]+">
            <xsl:matching-substring>
                <xsl:variable name="upperWord" select="substring(.,3)"/>
                <xsl:value-of select="concat($upperWord,'&#x200b;')"/>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

我期望的结果是:

<doc>
            <front>
                <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
                <para>​his is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
            </front>
            <front>
                <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
                <para>​his is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
            </front>
            <front>
                <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
                <para>​his is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
            </front>
        </doc>

    Output I got:

<doc>
        <front>
            <lable>this is a TEST TEXT</lable>
            <para>​his is a TEST TEXT with UPPER and Lower</para>
        </front>
        <middle>
            <lable>this is a TEST TEXT</lable>
            <para>​his is a TEST TEXT with UPPER and Lower</para>
        </middle>
        <back>
            <lable>​his is a TEST TEXT</lable>
            <para>​his is a TEST TEXT with UPPER and Lower</para>
        </back>
    </doc>

这是一个TES​;T-TEX​;T
​他的是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
​他的是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
​他的是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
我得到的输出:
这是一个测试文本
​his是一个包含上下两部分的测试文本
这是一个测试文本
​his是一个包含上下两部分的测试文本
​他的是一篇测试文章
​his是一个包含上下两部分的测试文本
在这里,我无法理解为什么选择单词的大写首字母以及为什么不选择所有文本节点。 有人能帮我解决这个问题吗。。 谢谢..

尝试更换

regex="^[A-Z]+"

试着替换

regex="^[A-Z]+"


您应该能够通过删除
xsl:analyze字符串
并仅使用
replace()
来简化它

注意:在我的示例中,我使用
xsl:charactermap
在文本中保留实体。您可以将其剥离,然后插入实际角色

例如。。。()

XML输入

<doc>
    <front>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </front>
    <middle>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </middle>
    <back>
        <lable>This is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </back>
</doc>
<doc>
   <front>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </front>
   <middle>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </middle>
   <back>
      <lable>This is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </back>
</doc>

这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
XSLT2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" use-character-maps="chars"/>
  <xsl:strip-space elements="*"/>

  <xsl:character-map name="chars">
    <xsl:output-character character="&#x200b;" string="&amp;#x200b;"/>
  </xsl:character-map>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()" priority="1">
      <xsl:value-of select="replace(.,'([A-Z]{3})','$1&#x200b;')"/>
  </xsl:template>

</xsl:stylesheet>

XML输出

<doc>
    <front>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </front>
    <middle>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </middle>
    <back>
        <lable>This is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </back>
</doc>
<doc>
   <front>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </front>
   <middle>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </middle>
   <back>
      <lable>This is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </back>
</doc>

这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低

您应该能够通过删除
xsl:analyze字符串
并使用
replace()
来简化它

注意:在我的示例中,我使用
xsl:charactermap
在文本中保留实体。您可以将其剥离,然后插入实际角色

例如。。。()

XML输入

<doc>
    <front>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </front>
    <middle>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </middle>
    <back>
        <lable>This is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </back>
</doc>
<doc>
   <front>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </front>
   <middle>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </middle>
   <back>
      <lable>This is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </back>
</doc>

这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
这是一个测试文本
这是一个带有上限和下限的测试文本
XSLT2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" use-character-maps="chars"/>
  <xsl:strip-space elements="*"/>

  <xsl:character-map name="chars">
    <xsl:output-character character="&#x200b;" string="&amp;#x200b;"/>
  </xsl:character-map>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()" priority="1">
      <xsl:value-of select="replace(.,'([A-Z]{3})','$1&#x200b;')"/>
  </xsl:template>

</xsl:stylesheet>

XML输出

<doc>
    <front>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </front>
    <middle>
        <lable>this is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </middle>
    <back>
        <lable>This is a TEST TEXT</lable>
        <para>This is a TEST TEXT with UPPER and Lower</para>
    </back>
</doc>
<doc>
   <front>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </front>
   <middle>
      <lable>this is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </middle>
   <back>
      <lable>This is a TES&#x200b;T TEX&#x200b;T</lable>
      <para>This is a TES&#x200b;T TEX&#x200b;T with UPP&#x200b;ER and Lower</para>
   </back>
</doc>

这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低
这是一个TES​;T-TEX​;T
这是一个TES​;T-TEX​;带UPP和x200b的T;呃和更低

谢谢Vegenta..regex通过替换这个运行得很好..但我的问题并没有完全解决Hanks Vegenta..regex通过替换这个运行得很好..但我的问题并没有完全解决Hanks..这很好..您能解释一下为什么xsl:analyze字符串给了我不正确的解决方案吗?@user2490093-这是因为您的regex匹配定位到字符串开头的一个或多个大写字母。然后使用
substring()
从匹配的第三个字符开始。因此,如果字符串以
This
开头,则匹配项仅为
T
,从第三个字符开始的子字符串不返回任何内容。零宽度空间得到输出;您就是看不到。@user2490093-如果您仍然需要
xsl:analyze string
答案,请告诉我。否则,如果此答案足够,请单击复选标记接受(✅) 在它旁边。谢谢..这起作用了..你能解释一下为什么这个xsl:analyze字符串给了我不正确的解决方案吗?@user2490093-这是因为你的正则表达式匹配了一个或多个锚定到字符串开头的大写字母。然后你使用
substring()
从匹配的第三个字符开始。因此,如果字符串以
This
开头,则匹配仅为
T
,从第三个字符开始的子字符串将不返回任何内容。但是,零宽度空间将得到输出;您只是看不到它。@user2490093-如果仍然需要
xsl:analyze字符串,请告诉我r、 否则,如果此答案足够,请单击复选标记接受(✅) 在它旁边。