XSLT中如何处理多字节Unicode字符转写以去除重音
解决XSLT中去除多字节Unicode字符重音的问题
你的核心需求是保留非西欧基础字母(如ɛ、ɔ)的同时,移除所有重音标记,之前的方法要么无法处理组合/多字节带重音字符,要么误删了需要保留的字母,以下是可行方案:
正确实现逻辑
使用normalize-unicode的NFKD模式将带重音字符分解为「基础字符+非间距重音标记」,再通过正则匹配删除所有重音标记(而非删除所有非基本拉丁字符):
replace(normalize-unicode($testwords, 'NFKD'), '\p{Mn}+', '')
逻辑说明
normalize-unicode($testwords, 'NFKD'):采用兼容性分解,将带重音的单个字符(如ɔ́、ɛ̀)拆分为基础字母(ɔ、ɛ)加上独立的非间距重音标记(Unicode类别Mn)。replace(..., '\p{Mn}+', ''):匹配所有连续的非间距重音标记并删除,仅保留基础字母,不会误删ɛ、ɔ这类非基本拉丁但需要保留的字符。
修改后的完整XSLT代码
<?xml version="1.0"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="text" encoding="UTF-8"/> <xsl:variable name="RSEP" select="' '"/> <!-- LF --> <xsl:template match="/"> <xsl:variable name="testwords" select="'à wɔ́rɔ, yɛrɛ, wùri'"/> <xsl:value-of select="$testwords"/> <xsl:value-of select="$RSEP"/> <!-- 正确的去重音逻辑 --> <xsl:value-of select="replace(normalize-unicode($testwords, 'NFKD'), '\p{Mn}+', '')"/> <xsl:value-of select="$RSEP"/> </xsl:template> </xsl:stylesheet>
输出结果
à wɔ́rɔ, yɛrɛ, wùri a wɔrɔ, yɛrɛ, wuri
为什么之前的方法失效?
translate:仅支持单个字符映射,无法处理组合型Unicode字符(或需手动枚举所有带重音变体,维护成本极高)。- 默认
normalize-unicode:默认使用NFC(规范合成)模式,若原字符已是合成后的单个字符,不会产生任何变化,必须指定NFKD模式才能分解重音。 replace(..., '\P{IsBasicLatin}', ''):该正则会删除所有非西欧基本拉丁字符,导致ɛ、ɔ这类需要保留的字母被误删。
内容的提问来源于stack exchange,提问作者Boyd
相关产品推荐
相关产品推荐

