Asosiy kontentga o‘tish
Innovialabs

O‘zbek lotin–kirill transliteratsiyasi kodda: qoidalar va tuzoqlar

Amaliyot5 daq

Qisqacha

Barcha apostroflar oldindan bitta belgiga keltirilsa, o‘zbek lotin yozuvini «avval ikki belgili birikmalar» tartibidagi jadval bilan kirillga ishonchli o‘girish mumkin; teskari o‘girish ma’lumot yo‘qotadi (ц, ў dan keyingi ъ), shuning uchun qidiruv uchun normallashtirilgan kalitni saqlang.

Qisqacha: transliteratsiya qanday ishlaydi

O‘zbek lotin va kirill yozuvlaridagi harflarning aksariyati bir-biriga birma-bir mos keladi. Qiyinchiliklarni uch narsa tug‘diradi:

  • apostroflar: foydalanuvchilar o‘ va g‘ da beshtagacha turli belgi ishlatadi;
  • digraflar: sh, ch, yo, ya yakka harflardan oldin aniqlanishi kerak;
  • kontekst: е, э va ц so‘zdagi o‘rniga bog‘liq, lotindan o‘girishda esa ma’lumotning bir qismi yo‘qoladi.

Ishchi sxema: apostroflarni normallashtirish → satr bo‘ylab avval uzun birikmalarni tekshirib yurish → registrni saqlash → munozarali so‘zlar uchun istisnolar lug‘atini yuritish.

Moslik jadvali

To‘g‘ridan-to‘g‘ri juftliklar: a–а, b–б, d–д, f–ф, g–г, i–и, j–ж, k–к, l–л, m–м, n–н, o–о, p–п, r–р, s–с, t–т, u–у, v–в, x–х, y–й, z–з.

LotinKirillIzoh
oʻ, gʻў, ғApostrof harfning bir qismi
hҳx = х bilan adashtirmang
qқ
sh, chш, чDigraflar, s, c dan oldin tekshiring
ngнгIkkala yozuvda ham ikki harf
yo, yu, yaё, ю, я
ye / eе / эQuyidagi qoidalarga qarang
s / tsцFaqat kirilldan o‘girishda
ʼъTutuq belgisi
—ьLotinda tushirib qoldiriladi

Apostroflar: o‘ va g‘

Haqiqiy ma’lumotlarda ASCII ' (U+0027), teskari apostrof, ‘ (U+2018), ’ (U+2019), ʻ (U+02BB) va ʼ (U+02BC) uchraydi. oʻ va gʻ uchun odatda U+02BB, tutuq belgisi uchun U+02BC tavsiya etiladi.

Normallashtirish qoidasi oddiy: harflar orasidagi istalgan apostrofni avval U+02BC ga, o va g dan keyin esa U+02BB ga aylantiramiz. So‘zlardan tashqaridagi apostroflarga, masalan qo‘shtirnoqlarga, tegmaymiz.

Digraf va kontekst tuzoqlari

  • yoʻl → йўл, ёл emas: yo dan keyin U+02BB kelsa, bu y + oʻ.
  • mingʻirlamoq → минғирламоқ: g dan keyin apostrof bo‘lsa, n va g ni «ng» ga birlashtirmang.
  • Isʼhoq → Исҳоқ: s va h orasidagi apostrof harflarni ajratadi, ш yoki ъ ni bildirmaydi.
  • е/э: lotindan o‘girishda so‘z boshida yoki unlidan keyin e — э (ertak → эртак), aks holda е; ye → е (yer → ер). Kirilldan esa aksincha: so‘z boshida va unlidan keyin е — ye (поезд → poyezd).
  • ц: kirilldan so‘z boshida va undoshdan keyin s (цирк → sirk), unlidan keyin ts (лицей → litsey). Teskari yo‘nalishda ц ni avtomatik tiklab bo‘lmaydi: ketsa — bu кетса. O‘zlashma so‘zlar lug‘ati kerak.
  • Kirilldagi ё har doim yo bo‘ladi.
  • Registr: kichik harf oldidagi Ш — Sh, butunlay katta harfli so‘z ichida — SH.

Lotin → kirill funksiyasi

const OKINA = "ʻ"; // ʻ in oʻ, gʻ
const TUTUQ = "ʼ"; // ʼ tutuq belgisi

function normalizeLatin(s) {
  return s
    .normalize("NFC")
    .replace(/(?<=\p{L})['`´‘’ʻʼ](?=\p{L})/gu, TUTUQ)
    .replace(/([oOgG])ʼ/g, "$1" + OKINA);
}

const L2C = [
  ["s" + TUTUQ + "h", "сҳ"], ["o" + OKINA, "ў"], ["g" + OKINA, "ғ"],
  ["sh", "ш"], ["ch", "ч"], ["yo", "ё"], ["yu", "ю"], ["ya", "я"], ["ye", "е"],
  ["a", "а"], ["b", "б"], ["d", "д"], ["f", "ф"], ["g", "г"], ["h", "ҳ"],
  ["i", "и"], ["j", "ж"], ["k", "к"], ["l", "л"], ["m", "м"], ["n", "н"],
  ["o", "о"], ["p", "п"], ["q", "қ"], ["r", "р"], ["s", "с"], ["t", "т"],
  ["u", "у"], ["v", "в"], ["x", "х"], ["y", "й"], ["z", "з"], [TUTUQ, "ъ"],
];

function latToCyr(input) {
  const s = normalizeLatin(input);
  let out = "";
  let i = 0;
  while (i < s.length) {
    const prev = s[i - 1] || "";
    let hit = null;
    for (const [lat, cyr] of L2C) {
      if (s.slice(i, i + lat.length).toLowerCase() !== lat) continue;
      if (lat === "yo" && s[i + 2] === OKINA) continue; // yoʻl -> йўл
      hit = [lat, cyr];
      break;
    }
    if (!hit && s[i].toLowerCase() === "e") {
      const startOrVowel = !/\p{L}/u.test(prev) || /[aeiou]/i.test(prev);
      hit = ["e", startOrVowel ? "э" : "е"];
    }
    if (!hit) { out += s[i++]; continue; }
    const [lat, cyr] = hit;
    const src = s.slice(i, i + lat.length);
    out += src[0] !== src[0].toLowerCase() ? cyr[0].toUpperCase() + cyr.slice(1) : cyr;
    i += lat.length;
  }
  return out;
}

Loyihada saqlab qo‘yishga arziydigan minimal testlar:

import assert from "node:assert/strict";
assert.equal(latToCyr("Oʻzbekiston"), "Ўзбекистон");
assert.equal(latToCyr("O’zbekiston"), "Ўзбекистон");
assert.equal(latToCyr("yo’l"), "йўл");
assert.equal(latToCyr("maʼno"), "маъно");
assert.equal(latToCyr("Is’hoq"), "Исҳоқ");
assert.equal(latToCyr("ertak"), "эртак");
assert.equal(latToCyr("SHAHAR"), "ШАҲАР");

Qidiruv uchun normallashtirish

Foydalanuvchilar o‘zlariga qulay tarzda qidiradi: apostrofsiz lotinda yoki ў, қ, ғ, ҳ harflarisiz rus klaviaturasidagi kirillda. Shuning uchun asl satrlarni emas, qidiruv kalitini solishtiring:

const FOLD = { ў: "у", қ: "к", ғ: "г", ҳ: "х", ъ: "", ь: "", ё: "е", э: "е" };

function searchKey(text) {
  return latToCyr(text)
    .toLowerCase()
    .replace(/[ўқғҳъьёэ]/g, (c) => FOLD[c])
    .replace(/\s+/g, " ")
    .trim();
}
// searchKey("Qo‘qon") === searchKey("Кукон")

Maslahatlar:

  • Kalitni alohida maydonda saqlang va indekslang, uni har safar qaytadan hisoblamang.
  • Asl matnni o‘zgartirmang: kalit faqat solishtirish uchun kerak.
  • Ozbekiston kabi apostrofsiz so‘rovlar ko‘p bo‘lsa, apostroflar shunchaki olib tashlanadigan ikkinchi kalit qo‘shing.

Ko‘p beriladigan savollar

Saqlash uchun bitta kanonik variantni, odatda U+02BB ni tanlang va barcha kiruvchi ma’lumotlarni unga keltiring. Ko‘rsatish uchun tipografik ‘ dan ham foydalanish mumkin, asosiysi — bazada variantlarni aralashtirmaslik.

Bunda yordam beramiz

O‘zingiz shug‘ullanmasdan natija olishni istasangiz — biz har kuni shu bilan shug‘ullanamiz.

Loyihani muhokama qilish

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.