You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android TTS语音名称美化解析求助:如何统一格式化语音名称

解析Android TTS语音名称到规范格式的实践方案

我之前做Android TTS相关项目时,真的被官方这乱七八糟的语音ID格式折腾得够呛!完全没有统一标准,每次刚摸出点规律,新的特殊格式就冒出来了。不过经过几次踩坑,总结出一套相对通用的解析思路,分享给你:

核心思路:分阶段拆解+多规则兼容

官方的语音ID大致可以分成几类,我们可以分步骤处理:

  1. 清理无关后缀
    先把-local、-network、-language这些不影响语言和性别的后缀去掉,用正则就能搞定:

    val cleanedName = rawName.replace(Regex("-(local|network|language)$"), "")
    
  2. 拆分语言核心与性别标识
    大部分带性别/序号的ID会用#分割,比如fr-fr-x-vlf#male_1,拆分后前面是语言区域标签,后面是性别信息。如果没有#,就只处理语言部分。

  3. 解析语言区域为友好名称
    用Android自带的Locale类来解析语言标签,转成中文的规范名称,比如en-gb转成“英语(英国)”。注意要处理大小写不一致的情况(比如uk-UA转成uk-ua再解析),还有单语言代码(比如cy、hr):

    val locale = runCatching { 
        Locale.forLanguageTag(coreTag.replace("_", "-").lowercase()) 
    }.getOrNull()
    val languageName = locale?.getDisplayName(Locale.CHINESE)?.replace("(", "(")?.replace(")", ")") 
                        ?: coreTag // 兜底显示原标签
    

    这里要注意,一些小语种的Locale默认中文名称可能缺失,需要手动维护一个映射表补充,比如:

    • cy → 威尔士语
    • hr → 克罗地亚语
    • bs → 波斯尼亚语
  4. 解析性别与序号
    对于#后面的部分,比如male_1、female_2,直接提取性别和数字转成中文:

    val genderLabel = genderPart?.let {
        when {
            it.startsWith("male_") -> "男性${it.substringAfter("_")}"
            it.startsWith("female_") -> "女性${it.substringAfter("_")}"
            else -> it // 遇到新格式时再补充规则
        }
    }
    

完整示例代码(Kotlin)

// 手动补充小语种名称映射
private val languageNameMap = mapOf(
    "cy" to "威尔士语",
    "hr" to "克罗地亚语",
    "bs" to "波斯尼亚语"
)

fun parseTtsVoiceName(rawName: String): String {
    // 步骤1:清理后缀
    val cleaned = rawName.replace(Regex("-(local|network|language)$"), "")
    // 步骤2:拆分核心标签和性别部分
    val parts = cleaned.split("#")
    val coreTag = parts[0]
    val genderPart = parts.getOrNull(1)
    
    // 步骤3:解析语言名称
    val languageName = languageNameMap[coreTag] ?: run {
        val locale = runCatching {
            Locale.forLanguageTag(coreTag.replace("_", "-").lowercase())
        }.getOrNull()
        locale?.getDisplayName(Locale.CHINESE)?.replace("(", "(")?.replace(")", ")") 
        ?: coreTag
    }
    
    // 步骤4:解析性别标签
    val genderLabel = genderPart?.let {
        when {
            it.startsWith("male_") -> "男性${it.substringAfter("_")}"
            it.startsWith("female_") -> "女性${it.substringAfter("_")}"
            else -> it
        }
    }
    
    // 组合结果
    return if (genderLabel != null) {
        "$languageName - $genderLabel"
    } else {
        languageName
    }
}

应对新格式的补充建议

因为官方没有公开统一的ID规范,后续遇到新的特殊格式时,可以:

  • 先观察新格式的结构,比如是否有新的分隔符或后缀
  • 扩展正则表达式和性别解析的条件分支
  • 补充小语种名称映射表

亲测用这套逻辑处理你列出的所有示例ID,都能得到符合要求的规范格式,比如:

  • en-gb-x-fis#female_1-local → 英语(英国)- 女性1
  • uk-UA-language → 乌克兰语
  • ja-jp-x-htm-network → 日语(日本)

内容的提问来源于stack exchange,提问作者Will Nixon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:57:59