编写XSLT函数检查字符串非ASCII字符并替换为下划线
XSLT替换非ASCII字符为下划线的实现思路
不需要手动创建非ASCII字符集再遍历字符串,XSLT不同版本有更高效的实现方式,分情况说明:
一、XSLT 2.0及以上版本(推荐)
利用原生的replace()函数结合正则表达式,就能快速完成替换,无需递归遍历:
1. 替换所有非ASCII字符
直接匹配ASCII范围(\x00-\x7F)之外的所有字符,替换为下划线:
<xsl:function name="my:replace-non-ascii" as="xs:string"> <xsl:param name="input" as="xs:string"/> <xsl:sequence select="replace($input, '[^\x00-\x7F]', '_')"/> </xsl:function>
2. 替换特定非ASCII字符集
如果只需要替换某一类非ASCII字符(比如西里尔字母、中文、日文等),可以通过Unicode字符类别或具体范围精准匹配:
- 示例1:只替换西里尔字母
<xsl:sequence select="replace($input, '[\p{Cyrillic}]', '_')"/>
- 示例2:只替换中文汉字(Unicode范围
\u4E00-\u9FFF)
<xsl:sequence select="replace($input, '[\u4E00-\u9FFF]', '_')"/>
二、XSLT 1.0版本(无正则支持)
由于XSLT 1.0没有原生正则,需要通过递归模板逐个字符检查处理:
1. 替换所有非ASCII字符
编写递归模板,通过codepoint-from-string()获取字符的Unicode码点,判断是否大于127(ASCII最大码点),是则替换为下划线,否则保留原字符:
<xsl:template name="replace-non-ascii"> <xsl:param name="input"/> <xsl:if test="$input != ''"> <xsl:variable name="first-char" select="substring($input, 1, 1)"/> <xsl:choose> <xsl:when test="codepoint-from-string($first-char) > 127">_</xsl:when> <xsl:otherwise><xsl:value-of select="$first-char"/></xsl:otherwise> </xsl:choose> <xsl:call-template name="replace-non-ascii"> <xsl:with-param name="input" select="substring($input, 2)"/> </xsl:call-template> </xsl:if> </xsl:template>
调用方式:
<xsl:call-template name="replace-non-ascii"> <xsl:with-param name="input" select="your-string-node"/> </xsl:call-template>
2. 替换特定非ASCII字符集
如果要匹配特定字符集,比如只替换À-ÿ范围内的拉丁扩展字符,可以用contains()函数判断字符是否在目标集合中:
<xsl:template name="replace-specific-non-ascii"> <xsl:param name="input"/> <xsl:if test="$input != ''"> <xsl:variable name="first-char" select="substring($input, 1, 1)"/> <!-- 定义目标非ASCII字符集 --> <xsl:variable name="target-chars" select="'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'"/> <xsl:choose> <xsl:when test="contains($target-chars, $first-char)">_</xsl:when> <xsl:otherwise><xsl:value-of select="$first-char"/></xsl:otherwise> </xsl:choose> <xsl:call-template name="replace-specific-non-ascii"> <xsl:with-param name="input" select="substring($input, 2)"/> </xsl:call-template> </xsl:if> </xsl:template>
核心思路总结
- 优先使用XSLT 2.0+的正则替换,代码简洁高效,无需手动遍历;
- 针对特定字符集,通过Unicode类别、字符范围或预定义字符集合实现精准匹配;
- XSLT 1.0下通过递归模板逐个处理字符,结合码点判断或
contains()完成替换。
内容的提问来源于stack exchange,提问作者RamAlx
相关产品推荐
相关产品推荐

