使用Java/Kotlin的Normalizer无法去除重音符号,求排查解决
解决Normalizer配合正则无法去除重音符号的问题
你的代码失效的核心原因是使用了错误的Unicode正则属性:\p{InCombiningDiacriticalMarks}是Unicode块(Block),仅覆盖U+0300-U+036F范围的组合重音,无法匹配所有类型的重音标记;而正确的做法是使用Unicode属性类\p{Mn}(对应Non-Spacing Mark,非间距标记),它能匹配所有组合型重音符号。
修正后的正则实现
import java.text.Normalizer const val INPUT = "áéíóůø" fun main() { // 先转换为NFD规范分解格式,拆分预组合字符为基础字符+重音标记 val nfdString = Normalizer.normalize(INPUT, Normalizer.Form.NFD) // 匹配并移除所有非间距标记(重音符号) val strippedString = nfdString.replace("\\p{Mn}+".toRegex(), "") println(strippedString) // 输出:aeiouo }
替代方案:遍历字符移除重音
如果担心正则的兼容性,可参考Apache Commons stripAccent的实现逻辑,直接遍历字符删除非间距标记:
import java.text.Normalizer import java.lang.Character.NON_SPACING_MARK const val INPUT = "áéíóůø" fun main() { val decomposed = StringBuilder(Normalizer.normalize(INPUT, Normalizer.Form.NFD)) var i = 0 while (i < decomposed.length) { if (Character.getType(decomposed[i]) == NON_SPACING_MARK) { decomposed.deleteCharAt(i) } else { i++ } } // 可选:转换回NFC规范组合格式 val result = Normalizer.normalize(decomposed, Normalizer.Form.NFC) println(result) // 输出:aeiouo }
内容的提问来源于stack exchange,提问作者Samuel Neff
相关产品推荐
相关产品推荐

