Skip to main content

Quy tắc số nhiều CLDR: Xác thực danh mục số nhiều i18n giữa các ngôn ngữ

Tiếng Anh có 2 dạng số nhiều. Tiếng Ả Rập có 6 dạng. Tiếng Nga có 4 dạng. Nếu cấu hình i18n của bạn chỉ xử lý 'one' và 'other', ứng dụng sẽ hoạt động sai trong hầu hết ngôn ngữ. Hướng dẫn này giải thích quy tắc số nhiều CLDR và cách xác thực các quy tắc đó.

1

Quy tắc số nhiều CLDR là gì?

Unicode CLDR (Kho dữ liệu ngôn ngữ chung) định nghĩa sáu danh mục số nhiều: zero, one, two, few, many và other. Mỗi ngôn ngữ sử dụng một tập con của các danh mục này với quy tắc số cụ thể. Tiếng Anh dùng one (chính xác là 1) và other (tất cả trường hợp còn lại). Tuy nhiên, hầu hết ngôn ngữ phức tạp hơn — dùng sai dạng số nhiều sẽ tạo ra câu sai ngữ pháp và khiến ứng dụng của bạn thiếu chuyên nghiệp.

The plural problem
// English has 2 plural forms: one, other
// "1 item" vs "2 items"

// But many languages have more:
// Arabic: 6 forms (zero, one, two, few, many, other)
// Polish: 3 forms (one, few, other)
// Japanese: 1 form (other)
// Czech: 3 forms (one, few, other)

// If you only provide "one" and "other",
// Arabic and Polish users see broken text.
Mọi ngôn ngữ đều bắt buộc có danh mục 'other'. Đây là danh mục dự phòng khi không có danh mục nào khác khớp. Nếu chỉ định nghĩa 'one' và 'other', bạn sẽ xử lý đúng tiếng Anh nhưng sai ở hơn 60% ngôn ngữ trên thế giới.
2

Sáu danh mục số nhiều

CLDR định nghĩa chính xác sáu danh mục số nhiều. Không phải ngôn ngữ nào cũng dùng cả sáu — tiếng Anh chỉ dùng hai còn tiếng Ả Rập dùng cả sáu. Tệp i18n của bạn phải định nghĩa những danh mục mà từng ngôn ngữ đích yêu cầu, nếu không người dùng có thể gặp sự cố, thấy khóa thô hoặc nội dung sai ngữ pháp.

CLDR plural categories
// CLDR defines 6 plural categories:
// zero  - 0 items (Arabic, Latvian)
// one   - 1 item (most languages)
// two   - 2 items (Arabic, Welsh)
// few   - 2-4 items (Polish, Czech, Russian)
// many  - 5-19 items (Arabic, Polish, Russian)
// other - everything else (required for ALL languages)

// Examples by language:
// English:  one, other                    (2 forms)
// French:   one, many, other              (3 forms)
// Arabic:   zero, one, two, few, many, other  (6 forms)
// Japanese: other                         (1 form)
// Polish:   one, few, many, other         (4 forms)
// Russian:  one, few, many, other         (4 forms)
3

Danh mục số nhiều theo ngôn ngữ

Bảng tham chiếu nhanh các danh mục số nhiều mà những ngôn ngữ đích phổ biến yêu cầu. Hãy dùng bảng này khi định nghĩa dạng số nhiều trong tệp bản dịch.

Common mistakes
// MISTAKE 1: Only providing "one" and "other"
// en.json
{
  "items_one": "{{count}} item",
  "items_other": "{{count}} items"
}
// This breaks for Arabic (missing zero, two, few, many)

// MISTAKE 2: Hardcoded plural logic
// WRONG:
const text = count === 1 ? "1 item" : `${count} items`
// This fails for languages where "1" isn't the only "one" form

// MISTAKE 3: Missing "other" category
// "other" is REQUIRED for every language
// Without it, some numbers show raw keys

// MISTAKE 4: Translating plural RULES instead of text
// The CLDR rules (one, few, many) are universal
// Only the TEXT after each rule should be translated
4

Tự động xác thực số nhiều

i18n-validate kiểm tra để bảo đảm mọi khóa số nhiều trong tệp bản dịch đều định nghĩa đủ các danh mục CLDR mà ngôn ngữ đích yêu cầu. Nếu tệp tiếng Nga chỉ có dạng 'one' và 'other', công cụ sẽ đánh dấu danh mục 'few' và 'many' còn thiếu là lỗi. Hãy chạy công cụ trong CI để phát hiện vấn đề về số nhiều trước khi chúng ảnh hưởng đến người dùng.

Terminal
# Validate plural forms match CLDR requirements
npx i18n-validate --check-plurals \
  --source locales/en.json \
  --targets 'locales/*.json'

# Output:
# locales/ar.json:
#   items: missing plural forms: zero, two, few, many
#   Expected: zero, one, two, few, many, other
#   Found: one, other
#
# locales/pl.json:
#   items: missing plural forms: few, many
#   Expected: one, few, many, other
#   Found: one, other

# Fix: Add all required forms for each language
# See https://unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
5

ICU MessageFormat cho dạng số nhiều

ICU MessageFormat là cách nên dùng để định nghĩa bản dịch số nhiều. Cú pháp này dùng một chuỗi duy nhất có nhúng quy tắc số nhiều: {count, plural, one {# item} other {# items}'}. react-intl, vue-i18n, Angular Transloco, Flutter và hầu hết framework i18n hiện đại đều hỗ trợ ICU.

ICU plural messages
// ICU MessageFormat handles plurals correctly
// It uses CLDR rules internally

// en.json
{
  "items": "{count, plural, one {# item} other {# items}}"
}

// ar.json
{
  "items": "{count, plural, zero {لا عناصر} one {عنصر واحد} two {عنصران} few {# عناصر} many {# عنصرًا} other {# عنصر}}"
}

// pl.json
{
  "items": "{count, plural, one {# element} few {# elementy} many {# elementów} other {# elementu}}"
}

// ICU also handles ordinals:
{
  "ranking": "{pos, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}"
}
Terminal
# Validate ICU message syntax
npx i18n-validate --check-icu \
  --source locales/en.json \
  --targets 'locales/*.json'

# Catches:
# - Missing plural categories for the target language
# - Syntax errors in ICU messages
# - Mismatched variable names
# - Missing "other" (always required)
Hệ thống thay ký hiệu # trong ICU MessageFormat bằng số lượng đã định dạng. Hãy dùng # thay vì ghi cứng tên biến trong các dạng số nhiều. Ví dụ, hãy viết '# item / # items' thay vì lặp lại biến số lượng một cách tường minh.

Dùng thử i18n Agent ngay

Thả tệp bản dịch của bạn vào đây

JSON, YAML, PO, XML, CSV, Markdown, Properties

hoặc nhấp để duyệt

Ngôn ngữ đích

Không cần đăng kýBáo giá tức thì

Câu hỏi thường gặp về quy tắc số nhiều CLDR