【前端国际化】ICU消息格式:处理复杂翻译场景
【前端国际化】ICU消息格式:处理复杂翻译场景
前言
大家好,我是cannonmonster01!上一篇我们聊了i18next的基本用法,今天咱们来深入聊聊ICU消息格式。如果你曾经遇到过复数处理、性别差异、日期格式化等复杂翻译场景,那么ICU消息格式就是你的救星!
什么是ICU消息格式
ICU(International Components for Unicode)是一套国际化支持库,ICU消息格式是其中的核心部分。它提供了一种强大的方式来处理复杂的翻译场景:
- 复数形式(Plurals)
- 性别形式(Gender)
- 选择形式(Select)
- 格式化(Formatting)
- 嵌套消息(Nested)
ICU消息格式的语法
基本语法
{占位符名, 类型, 格式}数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
| number | 数字格式化 | {count, number} |
| date | 日期格式化 | {date, date} |
| time | 时间格式化 | {time, time} |
| plural | 复数处理 | {count, plural, one {...} other {...}} |
| select | 选择处理 | {gender, select, male {...} female {...} other {...}} |
| selectordinal | 序数处理 | {rank, selectordinal, one {...} two {...}} |
复数处理
基本用法
// 翻译字符串 const message = '{count, plural, one {1 item} other {{count} items}}'; // 使用 formatMessage(message, { count: 1 }); // "1 item" formatMessage(message, { count: 5 }); // "5 items"复数类别
不同语言有不同的复数规则:
// 英语:one, other {count, plural, zero {No items} one {1 item} two {2 items} few {A few items} many {Many items} other {{count} items} }实际示例
{ "items": "{count, plural, one {1件商品} other {{count}件商品}}", "apples": "{count, plural, zero {没有苹果} one {1个苹果} other {{count}个苹果}}", "visitors": "{count, plural, one {一位访客} other {{count}位访客}}" }性别处理
基本用法
const message = '{gender, select, male {他} female {她} other {他们}}'; formatMessage(message, { gender: 'male' }); // "他" formatMessage(message, { gender: 'female' }); // "她" formatMessage(message, { gender: 'other' }); // "他们"组合使用
const message = '{gender, select, male {他有 {count, plural, one {1个苹果} other {{count}个苹果}} } female {她有 {count, plural, one {1个苹果} other {{count}个苹果}} } other {他们有 {count, plural, one {1个苹果} other {{count}个苹果}} } }'; formatMessage(message, { gender: 'male', count: 5 }); // "他有5个苹果"选择处理
基本用法
const message = '{role, select, admin {管理员} user {普通用户} guest {访客}}'; formatMessage(message, { role: 'admin' }); // "管理员" formatMessage(message, { role: 'user' }); // "普通用户"复杂示例
{ "accessLevel": "{level, select, guest {访客权限 - 仅可浏览} user {用户权限 - 可编辑} admin {管理员权限 - 完全控制} superadmin {超级管理员 - 所有权限} }" }格式化处理
数字格式化
// 基本数字 {price, number} // 1234.56 {price, number, integer} // 1235 {price, number, percent} // 123456% {price, number, currency} // $1,234.56 {price, number, #,##0.00} // 1,234.56日期格式化
// 日期格式 {date, date} // 2024/01/15 {date, date, short} // 1/15/24 {date, date, medium} // Jan 15, 2024 {date, date, long} // January 15, 2024 {date, date, full} // Monday, January 15, 2024 {date, date, year} // 2024 {date, date, month} // January {date, date, day} // 15时间格式化
// 时间格式 {time, time} // 10:30:00 AM {time, time, short} // 10:30 AM {time, time, medium} // 10:30:00 AM {time, time, long} // 10:30:00 AM GMT+8嵌套消息
基本嵌套
const message = '欢迎{name}加入我们的社区!您是第{count, plural, one {1位} other {{count}位}}成员。'; formatMessage(message, { name: '小明', count: 100 }); // "欢迎小明加入我们的社区!您是第100位成员。"多层嵌套
const message = '{gender, select, male {他是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} female {她是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} other {他们是第 {rank, selectordinal, one {一} two {二} other {{rank}}} 位用户} }';在i18next中使用ICU
安装插件
npm install i18next-icu配置
import i18n from 'i18next'; import ICU from 'i18next-icu'; import { initReactI18next } from 'react-i18next'; i18n .use(ICU) .use(initReactI18next) .init({ fallbackLng: 'zh', interpolation: { escapeValue: false } });使用示例
// locales/zh/common.json { "items": "{count, plural, one {1件商品} other {{count}件商品}}", "welcome": "欢迎{name}!今天是{date, date, long}。", "balance": "您的余额是{amount, number, currency}。" }import { useTranslation } from 'react-i18next'; const Component = () => { const { t } = useTranslation(); return ( <div> <p>{t('items', { count: 5 })}</p> <p>{t('welcome', { name: '小明', date: new Date() })}</p> <p>{t('balance', { amount: 1234.56 })}</p> </div> ); };在Vue中使用ICU
import { createI18n } from 'vue-i18n'; import { ICUMessageFormatPlugin } from '@vue/composition-api'; const i18n = createI18n({ legacy: false, locale: 'zh', fallbackLocale: 'zh', messages: { zh: { items: '{count, plural, one {1件商品} other {{count}件商品}}' }, en: { items: '{count, plural, one {1 item} other {{count} items}}' } }, plugins: [ICUMessageFormatPlugin] });复数规则详解
CLDR复数类别
| 类别 | 说明 | 适用语言 |
|---|---|---|
| zero | 零 | 阿拉伯语等 |
| one | 一 | 英语、法语等 |
| two | 二 | 阿拉伯语、威尔士语 |
| few | 少数 | 俄语、波兰语等 |
| many | 多数 | 阿拉伯语、希腊语等 |
| other | 其他 | 所有语言 |
英语复数规则
// 英语:1用one,其他用other {count, plural, one {1 item} other {{count} items}}俄语复数规则
// 俄语:1用one,2-4用few,其他用many {count, plural, one {{count} предмет} few {{count} предмета} many {{count} предметов}}中文复数规则
// 中文:通常不需要复数变化 {count, plural, other {{count}件商品}}最佳实践
保持翻译简洁
// 好的示例 {count, plural, one {1个苹果} other {{count}个苹果}} // 避免重复 {count, plural, one {有1个苹果} other {有{count}个苹果}}使用默认值
// 提供默认值 {name, select, male {他} female {她} other {用户}}测试各种场景
// 测试边界情况 test('复数处理', () => { expect(formatMessage('{count, plural, one {1} other {{count}}}', { count: 0 })).toBe('0'); expect(formatMessage('{count, plural, one {1} other {{count}}}', { count: 1 })).toBe('1'); expect(formatMessage('{count, plural, one {1} other {{count}}}', { count: 100 })).toBe('100'); });工具支持
ICU Message Editor
这是一个在线工具,可以帮助你编写和测试ICU消息格式:
- 官网:https://format-message.github.io/icu-message-editor/
i18next-parser配置
module.exports = { options: { interpolation: { formatSeparator: ',' }, parseICU: true } };总结
ICU消息格式是处理复杂翻译场景的利器,通过今天的学习,相信你已经掌握了:
- ICU消息格式的基本语法
- 复数处理的用法
- 性别和选择处理
- 日期和数字格式化
- 嵌套消息的使用
- 在i18next和Vue中的集成
掌握ICU消息格式,让你的国际化应用更加专业和完善!
