XSLT 正则表达式 - 后面没有
XSLT regex - not followed by
我需要找到 ','
后面没有跟 space 的文本,并在 XSLT 中为每个文本显式添加一个 space 值。
示例:
输入:
<chap>
<para>10,20,30,40,50,60,</para>
<para>10, 20, 30, 40, 50, 60</para>
</chap>
输出:
<chap>
<para>10, 20, 30, 40, 50, 60, 60, </para>
<para>10, 20, 30, 40, 50, 60</para>
</chap>
XSLT
<xsl:template match="text()">
<xsl:analyze-string select="." regex=",(?!\s)">
<xsl:matching-substring>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
我可以使用正则表达式来完成这项任务,但任何人都可以建议我如何找到 ','
文本 后面没有跟 space
字符?
您可以使用 replace()
函数来替换后跟非空白字符的逗号,例如 $x
,用逗号 +  
+ 非空白字符 $x
:
<xsl:template match="para">
<xsl:copy>
<xsl:value-of select="replace(.,',(\S)',', ')"/>
</xsl:copy>
</xsl:template>
这是一个支持 exslt 的 xslt-1.0 解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="fn str">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="/node()"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="./@*"/>
<xsl:apply-templates select="./node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="text()[contains(., ',')][count(str:split(., ',')) > count(str:split(., ', '))]">
<xsl:choose>
<xsl:when test="contains(., ',')">
<xsl:for-each select="str:tokenize(., ', ')">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
最后一个文本模板仅匹配包含“,”但后跟 space
的文本
我愿意
string-join(tokenize($in, ',\s*'), ', ')
这是假设用单个 space.
替换逗号后的多个 space 是可以接受的
(刚刚注意到@pouyan 已经在评论中建议了这种方法)。
我需要找到 ','
后面没有跟 space 的文本,并在 XSLT 中为每个文本显式添加一个 space 值。
示例:
输入:
<chap>
<para>10,20,30,40,50,60,</para>
<para>10, 20, 30, 40, 50, 60</para>
</chap>
输出:
<chap>
<para>10, 20, 30, 40, 50, 60, 60, </para>
<para>10, 20, 30, 40, 50, 60</para>
</chap>
XSLT
<xsl:template match="text()">
<xsl:analyze-string select="." regex=",(?!\s)">
<xsl:matching-substring>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
我可以使用正则表达式来完成这项任务,但任何人都可以建议我如何找到 ','
文本 后面没有跟 space
字符?
您可以使用 replace()
函数来替换后跟非空白字符的逗号,例如 $x
,用逗号 +  
+ 非空白字符 $x
:
<xsl:template match="para">
<xsl:copy>
<xsl:value-of select="replace(.,',(\S)',', ')"/>
</xsl:copy>
</xsl:template>
这是一个支持 exslt 的 xslt-1.0 解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="fn str">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="/node()"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="./@*"/>
<xsl:apply-templates select="./node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="text()[contains(., ',')][count(str:split(., ',')) > count(str:split(., ', '))]">
<xsl:choose>
<xsl:when test="contains(., ',')">
<xsl:for-each select="str:tokenize(., ', ')">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
最后一个文本模板仅匹配包含“,”但后跟 space
的文本我愿意
string-join(tokenize($in, ',\s*'), ', ')
这是假设用单个 space.
替换逗号后的多个 space 是可以接受的(刚刚注意到@pouyan 已经在评论中建议了这种方法)。