Skip to content

Instantly share code, notes, and snippets.

@diolavr
Last active April 27, 2024 10:28
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save diolavr/d2d50686cb5a472f5696 to your computer and use it in GitHub Desktop.
Save diolavr/d2d50686cb5a472f5696 to your computer and use it in GitHub Desktop.
JavaScript translater russian to translit
function rus_to_latin ( str ) {
var ru = {
'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya'
}, n_str = [];
str = str.replace(/[ъь]+/g, '').replace(/й/g, 'i');
for ( var i = 0; i < str.length; ++i ) {
n_str.push(
ru[ str[i] ]
|| ru[ str[i].toLowerCase() ] == undefined && str[i]
|| ru[ str[i].toLowerCase() ].toUpperCase()
);
}
return n_str.join('');
}
/*
rus_to_latin( 'Иван Алексеев, известный под сценической кличкой Noize MC записал альбом с показательным названием «Неразбериха». Получилась питательная и где-то даже успокоительная смесь из хип-хопа, гранжа, регги и брейк-бита' );
> Ivan Alekseev, izvestnyi pod scenicheskoi klichkoi Noize MC zapisal albom s pokazatelnym nazvaniem «Nerazberiha». Poluchilas pitatelnaya i gde-to daje uspokoitelnaya smes iz hip-hopa, granja, reggi i breik-bita
*/
@filippovdima5
Copy link

Спасибо!)

@Mikkou
Copy link

Mikkou commented Mar 17, 2020

thanks!

@RaptorII
Copy link

RaptorII commented Apr 14, 2020

спсб.

@addictional
Copy link

addictional commented Apr 27, 2020

Моя версия, тут нет регулярок, должно работать быстрее

function convertToLatine(string) {
    const min = 1072,
      max = 1105;

    const ru = [
      "a",
      "b",
      "v",
      "g",
      "d",
      "e",
      "j",
      "z",
      "i",
      "i",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "r",
      "s",
      "t",
      "u",
      "f",
      "h",
      "c",
      "ch",
      "sh",
      "shch",
      "",
      "y",
      "",
      "e",
      "u",
      "ya",
      "",
      "yo",
    ];
    let translate = "";

    for (let i = 0; i < str.length; i++) {
      const charCode = str[i].toLowerCase().charCodeAt(0);
      if (charCode >= min && charCode <= max) {
        let newChar = ru[charCode - min];
        if (str[i] == str[i].toUpperCase()) {
          if (newChar.length > 1) {
            newChar = newChar.split("").reduce((prev, next, index) => {
              if (index == 1) {
                return prev.toUpperCase() + next;
              } else {
                return prev + next;
              }
            });
          } else {
            newChar = newChar.toUpperCase();
          }
        }
        translate += newChar;
      } else {
        translate += str[i];
      }
    }

    return translate;
  }

Тесты:

describe("testing convert function", () => {
  it("should return empty string if empty string in params", () => {
    const str = Utils.convertToLatine("");
    expect(str).toEqual("");
  });
  it("if any of chars in upper case shoud return convert of this char in upper case", () => {
    expect(Utils.convertToLatine("гГ")).toEqual("gG");
    expect(Utils.convertToLatine("Яя")).toEqual("Yaya");
  });
  it("should convert right", () => {
    expect(
      Utils.convertToLatine(
        "Шла саша по шоссе и нашла сушку. А сушка стоила 100 рублей. На дрогу вышел ЁжЪь!!!!"
      )
    ).toEqual(
      "Shla sasha po shosse i nashla sushku. A sushka stoila 100 rublei. Na drogu vyshel Yoj!!!!"
    );
  });
});

@cawa-93
Copy link

cawa-93 commented Aug 18, 2020

Чуть осовремененая версия, если кто любит "современные штучки"

function rus_to_latin(str) {

	const ru = new Map([
		['а', 'a'], ['б', 'b'], ['в', 'v'], ['г', 'g'], ['д', 'd'], ['е', 'e'],
		['є', 'e'], ['ё', 'e'], ['ж', 'j'], ['з', 'z'], ['и', 'i'], ['ї', 'yi'], ['й', 'i'],
		['к', 'k'], ['л', 'l'], ['м', 'm'], ['н', 'n'], ['о', 'o'], ['п', 'p'], ['р', 'r'],
		['с', 's'], ['т', 't'], ['у', 'u'], ['ф', 'f'], ['х', 'h'], ['ц', 'c'], ['ч', 'ch'],
		['ш', 'sh'], ['щ', 'shch'], ['ы', 'y'], ['э', 'e'], ['ю', 'u'], ['я', 'ya'],
	]);

	str = str.replace(/[ъь]+/g, '');

	return Array.from(str)
		.reduce((s, l) =>
			s + (
				  ru.get(l)
				  || ru.get(l.toLowerCase()) === undefined && l
				  || ru.get(l.toLowerCase()).toUpperCase()
			  )
			, '');
}

@diolavr
Copy link
Author

diolavr commented Aug 20, 2020

Чуть осовремененая версия, если кто любит "современные штучки"

function rus_to_latin(str) {

	const ru = new Map([
		['а', 'a'], ['б', 'b'], ['в', 'v'], ['г', 'g'], ['д', 'd'], ['е', 'e'],
		['є', 'e'], ['ё', 'e'], ['ж', 'j'], ['з', 'z'], ['и', 'i'], ['ї', 'yi'], ['й', 'i'],
		['к', 'k'], ['л', 'l'], ['м', 'm'], ['н', 'n'], ['о', 'o'], ['п', 'p'], ['р', 'r'],
		['с', 's'], ['т', 't'], ['у', 'u'], ['ф', 'f'], ['х', 'h'], ['ц', 'c'], ['ч', 'ch'],
		['ш', 'sh'], ['щ', 'shch'], ['ы', 'y'], ['э', 'e'], ['ю', 'u'], ['я', 'ya'],
	]);

	str = str.replace(/[ъь]+/g, '');

	return Array.from(str)
		.reduce((s, l) =>
			s + (
				  ru.get(l)
				  || ru.get(l.toLowerCase()) === undefined && l
				  || ru.get(l.toLowerCase()).toUpperCase()
			  )
			, '');
}

Выглядит бодро! 👍

@gulik17
Copy link

gulik17 commented Nov 25, 2020

Чуть осовремененая версия, если кто любит "современные штучки"

Компакт версия

function transliterate(word) {
  const keys = {
    'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
    'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
    'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
    'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
    'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
    'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya'
  }
  return word.split("").map((char) => keys[char] || char).join("");
}

@cawa-93
Copy link

cawa-93 commented Nov 25, 2020

Чуть осовремененая версия, если кто любит "современные штучки"

Компакт версия
function transliterate(word) {
const keys = {
'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya'
}
return word.split("").map((char) => keys[char] || char).join("");
}

Не работает с верхним регистром

@ungarson
Copy link

@cawa-93, думаю, можно просто uppercase keys добавить)) 😅

@numfin
Copy link

numfin commented Dec 2, 2020

Чуть осовремененая версия, если кто любит "современные штучки"

function rus_to_latin(str) {

	const ru = new Map([
		['а', 'a'], ['б', 'b'], ['в', 'v'], ['г', 'g'], ['д', 'd'], ['е', 'e'],
		['є', 'e'], ['ё', 'e'], ['ж', 'j'], ['з', 'z'], ['и', 'i'], ['ї', 'yi'], ['й', 'i'],
		['к', 'k'], ['л', 'l'], ['м', 'm'], ['н', 'n'], ['о', 'o'], ['п', 'p'], ['р', 'r'],
		['с', 's'], ['т', 't'], ['у', 'u'], ['ф', 'f'], ['х', 'h'], ['ц', 'c'], ['ч', 'ch'],
		['ш', 'sh'], ['щ', 'shch'], ['ы', 'y'], ['э', 'e'], ['ю', 'u'], ['я', 'ya'],
	]);

	str = str.replace(/[ъь]+/g, '');

	return Array.from(str)
		.reduce((s, l) =>
			s + (
				  ru.get(l)
				  || ru.get(l.toLowerCase()) === undefined && l
				  || ru.get(l.toLowerCase()).toUpperCase()
			  )
			, '');
}

Спасибо за полезный снипет, на всякий приложу для остальных понятную для чтения версию.

const ru = {
  а: 'a',
  б: 'b',
  в: 'v',
  г: 'g',
  д: 'd',
  е: 'e',
  є: 'e',
  ё: 'e',
  ж: 'j',
  з: 'z',
  и: 'i',
  ї: 'yi',
  й: 'i',
  к: 'k',
  л: 'l',
  м: 'm',
  н: 'n',
  о: 'o',
  п: 'p',
  р: 'r',
  с: 's',
  т: 't',
  у: 'u',
  ф: 'f',
  х: 'h',
  ц: 'c',
  ч: 'ch',
  ш: 'sh',
  щ: 'shch',
  ы: 'y',
  э: 'e',
  ю: 'u',
  я: 'ya',
  ъ: '',
  ь: '',
};

export function rusToLatin(str) {
  return Array.from(str).reduce((acc, letter) => {
    const lowLetter = letter.toLowerCase();
    const en = ru[lowLetter] ?? letter;
    const enNormalized = lowLetter === letter ? en : en.toUpperCase();
    return acc + enNormalized;
  }, '');
}

@maksam07
Copy link

Не работает с верхним регистром

На основе последнего скрипта - подправил:

const ruKeys = {
    'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
    'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
    'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
    'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
    'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
    'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya'
}

function transliterate(word) {
    return word.split("").map((letter) => {
        const lowLetter = letter.toLowerCase();
        const en = ruKeys[lowLetter] ?? letter;
        return lowLetter === letter ? en : en.toUpperCase();
    }).join("");
}

@MaximLukianchuk
Copy link

Не работает с верхним регистром

На основе последнего скрипта - подправил:

const ruKeys = {
    'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
    'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
    'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
    'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
    'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh',
    'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya'
}

function transliterate(word) {
    return word.split("").map((letter) => {
        const lowLetter = letter.toLowerCase();
        const en = ruKeys[lowLetter] ?? letter;
        return lowLetter === letter ? en : en.toUpperCase();
    }).join("");
}

Наверное не стоит оставлять в транслите мягкий и твердый знак и добавить что-то вроде:

...return word.replace(/[ъь]+/g, '').split("").map((letter) => {...

@leo-at-itartpro
Copy link

leo-at-itartpro commented Apr 2, 2021

Наверное не стоит оставлять в транслите мягкий и твердый знак и добавить что-то вроде:

...return word.replace(/[ъь]+/g, '').split("").map((letter) => {...

Ну и без regex, для целостности:
в ключах можно обозначить 'ь': '' пустыми строками...которые НЕ undefined и будут заменятся, а всякие спец символы и т.д. типо $ будут пропускатся так как мы не обозначили их в ключах
return str.split("").map(char => typeof keys[char] === "undefined" ? char : keys[char]).join("");

Моя полная версия...скажете длинная но мне нравится доп контроль над символами:

const translit = str => {
    const keys = {
        'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd',
        'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
        'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o',
        'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
        'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch','ш': 'sh',
        'ь': '',  'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya',
        'щ': 'shch', 'ъ': '',

        'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D',
        'Е': 'E', 'Ё': 'E', 'Ж': 'J', 'З': 'Z', 'И': 'I',
        'К': 'K', 'Л': 'L', 'М': 'M', 'Н': 'N', 'О': 'O',
        'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U',
        'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch','Ш': 'Sh',
        'Ь': '',  'Ы': 'Y', 'Э': 'E', 'Ю': 'U', 'Я': 'Ya',
        'Щ': 'Shch', 'Ъ':''
    }

    return str.split("").map(char => typeof keys[char] === "undefined" ? char : keys[char]).join("");
}

@OrangeBox33
Copy link

СПАСИБО!

@monkekode
Copy link

monkekode commented Nov 15, 2021

В последней версии не работает й. Вот рабочая версия на TS, с поддержкой украинских букв. Результат совпадает с текстом в стартовом посте:

const ruKeys: Record<string, string> = {
    'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'e', 'ж': 'j', 'з': 'z', 'и': 'i',
    'к': 'k', 'л': 'l', 'м': 'm', 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
    'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'shch', 'ы': 'y', 'э': 'e', 'ю': 'u', 'я': 'ya',
    'й': 'i', 'ъ': '', 'ь': '', 'і': 'i', 'ї': 'yi', 'є': 'ye'
};

function transliterate(word: string) {
    return word.split("").map((letter) => {
        const lowLetter = letter.toLowerCase();
        const en = ruKeys[lowLetter] ?? letter;
        return lowLetter === letter ? en : (en.slice(0,1).toUpperCase() + en.slice(1);
    }).join("");
}

const test = 'і є ї Щваньъ Алексеев, известный под сценической кличкой Noize MC записал альбом с показательным названием «Неразбериха». Получилась питательная и где-то даже успокоительная смесь из хип-хопа, гранжа, регги и брейк-бита';
const expected = 'i ye yi Shchvan Alekseev, izvestnyi pod scenicheskoi klichkoi Noize MC zapisal albom s pokazatelnym nazvaniem «Nerazberiha». Poluchilas pitatelnaya i gde-to daje uspokoitelnaya smes iz hip-hopa, granja, reggi i breik-bita';

console.log(transliterate(test) == expected);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment