Как транслитерировать текст с кириллицы на латиницу

У меня есть метод, который превращает любой текст на латинице (например, английский, французский, немецкий, польский) в его краткую форму,

e.g. Alpha Bravo Charlie => alpha-bravo-charlie

Но он не может работать с кириллическим текстом (например, русским), поэтому я хочу транслитерировать кириллический текст в латинские символы, а затем обработать его.

У кого-нибудь есть способ сделать такую ​​транслитерацию? Будь то фактический источник или библиотека.

Я пишу код на C#, поэтому подойдет библиотека .NET. В качестве альтернативы, если у вас есть код, отличный от C #, я уверен, что смогу его преобразовать.


person ckknight    schedule 03.12.2009    source источник


Ответы (10)


Вы можете использовать dll-библиотеку с открытым исходным кодом .NET UnidecodeSharpFork для транслитерации кириллицы и многого другого. языков на латынь.

Пример использования:

Assert.AreEqual("Rabota s kirillitsey", "Работа с кириллицей".Unidecode());
Assert.AreEqual("CZSczs", "ČŽŠčžš".Unidecode());
Assert.AreEqual("Hello, World!", "Hello, World!".Unidecode());

Проверка кириллицы:

/// <summary>
/// According to http://en.wikipedia.org/wiki/Romanization_of_Russian BGN/PCGN.
/// http://en.wikipedia.org/wiki/BGN/PCGN_romanization_of_Russian
/// With converting "ё" to "yo".
/// </summary>
[TestMethod]
public void RussianAlphabetTest()
{
    string russianAlphabetLowercase = "а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я";
    string russianAlphabetUppercase = "А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я";

    string expectedLowercase = "a b v g d e yo zh z i y k l m n o p r s t u f kh ts ch sh shch \" y ' e yu ya";
    string expectedUppercase = "A B V G D E Yo Zh Z I Y K L M N O P R S T U F Kh Ts Ch Sh Shch \" Y ' E Yu Ya";

    Assert.AreEqual(expectedLowercase, russianAlphabetLowercase.Unidecode());
    Assert.AreEqual(expectedUppercase, russianAlphabetUppercase.Unidecode());
}

Простой, быстрый и мощный. И при желании легко расширить/изменить таблицу транслитерации.

person Dima Stefantsov    schedule 18.06.2012
comment
Неправильный. Это транслитерирует Анастасия как Анастасия, а не Анастасия. Это выглядит ужасно. Похоже, этот документ ( en.wikipedia.org/wiki/BGN/PCGN_romanization_of_Russian) неправильно в специальных положениях. Кроме того, вы не принимаете во внимание специальные положения, и UnidecodeSharpFork транслитерирует немецкие умляуты (äöüÄÖÜ) как aouAOU вместо ae oe ue Ae Oe Ue. Вот почему я перешел с Upvote на Downvote. Если вы делаете библиотеку латинизации (или алгоритм), делайте это правильно или иным образом заявляйте, что ваш алгоритм неполный/глючный и не готов к работе. - person Stefan Steiger; 25.12.2012
comment
Я использую этот обходной путь: string str = this.Name.Replace(ь, ); str = str.Replace(ä, ae); str = str.Replace(ö, oe); str = str.Replace(ü, ue); str = str.Replace(Ä, Ae); str = str.Replace(Ö, Oe); str = str.Replace(Ü, Ue); str = UnidecodeSharpFork.Unidecoder.Unidecode(str); //str = str.Replace(Анастасия, Анастасия); str = str.Replace(iy, i); // вернуть this.Name.Unidecode(); вернуть ул; - person Stefan Steiger; 25.12.2012
comment
Если вы делаете библиотеку латинизации, я этого не делаю. Это просто транслитерация каждой буквы на английский/латиницу. И это ДАЛЕКО от совершенства, но оно работает для многих языков. Например, dotabro.com/player/76561198060110736/madgaming-crio-j-jinmawang Я использую его, потому что ссылки лучше, чем ничего. - person Dima Stefantsov; 25.12.2012
comment
Транслитерация @DimaStefantsov предполагает взаимно однозначное отображение символов одной письменности в другую. Преобразование «ä» в «а» нарушает это правило, так как нет способа однозначно транслитерировать текст обратно в оригинал (теперь есть способ узнать, какой символ представляет «а» в оригинале). Существуют четко определенные стандарты транслитерации, которые определяют, как транслитерируется определенная система письма. Даже если у вас есть одно и то же слово на кириллице, в болгарском оно будет латинизироваться иначе, чем в сербском. Вы не можете сделать транслитерацию, не зная, на каком языке написан текст. - person Igor Brejc; 06.12.2016
comment
@ДимаСтефанцов (продолжение). Я хочу сказать, что вы не должны утверждать, что ваша библиотека выполняет транслитерацию, если это не так. Но я знаю, что исходные библиотеки, которые вы использовали, также утверждают это, так что я думаю, что это их первородный грех. Чтобы расширить вашу библиотеку для транслитерации, вам нужно будет предоставить отдельные наборы правил для разных языков (русский, сербский, греческий и т. д.) - даже отдельные наборы правил для разных стандартов транслитерации (у современного греческого языка есть как минимум 5 или 6 различных). И укажите идентификатор языка (идентификатор культуры) в качестве входного параметра для транслитерации. - person Igor Brejc; 06.12.2016

Почему нельзя просто взять таблицу транслитерации и сделать небольшое регулярное выражение или подпрограмму?

person Max Galkin    schedule 03.12.2009
comment
Ну... может оказаться проще, чем я думал. Попробую, спасибо. - person Veverke; 21.09.2015

Оптимизирован ответ Сарвара Нишонбоева, кажется самым простым решением без ненужной сложности, связанной с повторным созданием строки на каждой итерации. :

public static class Converter
{
    private static readonly Dictionary<char, string> ConvertedLetters = new Dictionary<char, string>
    {
        {'а', "a"},
        {'б', "b"},
        {'в', "v"},
        {'г', "g"},
        {'д', "d"},
        {'е', "e"},
        {'ё', "yo"},
        {'ж', "zh"},
        {'з', "z"},
        {'и', "i"},
        {'й', "j"},
        {'к', "k"},
        {'л', "l"},
        {'м', "m"},
        {'н', "n"},
        {'о', "o"},
        {'п', "p"},
        {'р', "r"},
        {'с', "s"},
        {'т', "t"},
        {'у', "u"},
        {'ф', "f"},
        {'х', "h"},
        {'ц', "c"},
        {'ч', "ch"},
        {'ш', "sh"},
        {'щ', "sch"},
        {'ъ', "j"},
        {'ы', "i"},
        {'ь', "j"},
        {'э', "e"},
        {'ю', "yu"},
        {'я', "ya"},
        {'А', "A"},
        {'Б', "B"},
        {'В', "V"},
        {'Г', "G"},
        {'Д', "D"},
        {'Е', "E"},
        {'Ё', "Yo"},
        {'Ж', "Zh"},
        {'З', "Z"},
        {'И', "I"},
        {'Й', "J"},
        {'К', "K"},
        {'Л', "L"},
        {'М', "M"},
        {'Н', "N"},
        {'О', "O"},
        {'П', "P"},
        {'Р', "R"},
        {'С', "S"},
        {'Т', "T"},
        {'У', "U"},
        {'Ф', "F"},
        {'Х', "H"},
        {'Ц', "C"},
        {'Ч', "Ch"},
        {'Ш', "Sh"},
        {'Щ', "Sch"},
        {'Ъ', "J"},
        {'Ы', "I"},
        {'Ь', "J"},
        {'Э', "E"},
        {'Ю', "Yu"},
        {'Я', "Ya"}
    };

    public static string ConvertToLatin(string source)
    {
        var result = new StringBuilder();
        foreach (var letter in source)
        {
            result.Append(ConvertedLetters[letter]);
        }
        return result.ToString();
    }
}

Используйте это так:

Converter.ConvertToLatin("Проверочный текст");
person Schnapz    schedule 17.07.2019
comment
Обратите внимание, что этот код вызовет исключение, если в исходной строке есть какой-либо латинский символ... - person Konrad; 15.04.2021

Проверьте этот код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Transliter
{
    public partial class Form1 : Form
    {
        Dictionary<string, string> words = new Dictionary<string, string>();

        public Form1()
        {
            InitializeComponent();
            words.Add("а", "a");
            words.Add("б", "b");
            words.Add("в", "v");
            words.Add("г", "g");
            words.Add("д", "d");
            words.Add("е", "e");
            words.Add("ё", "yo");
            words.Add("ж", "zh");
            words.Add("з", "z");
            words.Add("и", "i");
            words.Add("й", "j");
            words.Add("к", "k");
            words.Add("л", "l");
            words.Add("м", "m");
            words.Add("н", "n");
            words.Add("о", "o");
            words.Add("п", "p");
            words.Add("р", "r");
            words.Add("с", "s");
            words.Add("т", "t");
            words.Add("у", "u");
            words.Add("ф", "f");
            words.Add("х", "h");
            words.Add("ц", "c");
            words.Add("ч", "ch");
            words.Add("ш", "sh");
            words.Add("щ", "sch");
            words.Add("ъ", "j");
            words.Add("ы", "i");
            words.Add("ь", "j");
            words.Add("э", "e");
            words.Add("ю", "yu");
            words.Add("я", "ya");
            words.Add("А", "A");
            words.Add("Б", "B");
            words.Add("В", "V");
            words.Add("Г", "G");
            words.Add("Д", "D");
            words.Add("Е", "E");
            words.Add("Ё", "Yo");
            words.Add("Ж", "Zh");
            words.Add("З", "Z");
            words.Add("И", "I");
            words.Add("Й", "J");
            words.Add("К", "K");
            words.Add("Л", "L");
            words.Add("М", "M");
            words.Add("Н", "N");
            words.Add("О", "O");
            words.Add("П", "P");
            words.Add("Р", "R");
            words.Add("С", "S");
            words.Add("Т", "T");
            words.Add("У", "U");
            words.Add("Ф", "F");
            words.Add("Х", "H");
            words.Add("Ц", "C");
            words.Add("Ч", "Ch");
            words.Add("Ш", "Sh");
            words.Add("Щ", "Sch");
            words.Add("Ъ", "J");
            words.Add("Ы", "I");
            words.Add("Ь", "J");
            words.Add("Э", "E");
            words.Add("Ю", "Yu");
            words.Add("Я", "Ya");
    }

        private void button1_Click(object sender, EventArgs e)
        {
            string source = textBox1.Text;
            foreach (KeyValuePair<string, string> pair in words)
            {
                source = source.Replace(pair.Key, pair.Value);
            }
            textBox2.Text = source;
        }
    }
}

криллик на латиницу:

text.Replace(pair.Key, pair.Value); 

с латыни на криллик

source.Replace(pair.Value,pair.Key);
person Sarvar Nishonboyev    schedule 12.09.2014
comment
Давайте создадим 66*(количество символов) строк... хорошо. - person hazzik; 24.01.2015

Вы можете использовать мою библиотеку для транслитерации: https://github.com/nick-buhro/Translit
Он также доступен на NuGet.

Пример:

var latin = Transliteration.CyrillicToLatin(
    "Предками данная мудрость народная!", 
    Language.Russian);

Console.WriteLine(latin);   
// Output: Predkami dannaya mudrost` narodnaya!
person Nick Buhro    schedule 26.03.2016

У Microsoft есть инструмент транслитерации, который включает DLL, к которой вы можете подключиться (вам нужно будет проверить лицензионные ограничения, если вы собираетесь использовать его не лично). Подробнее об этом можно прочитать в Сообщение в блоге Деяна Весича

person jball    schedule 03.12.2009

Для будущих читателей

Windows 7+ может сделать это с помощью своего Расширенные лингвистические услуги. (Чтобы сделать это из .NET, вам понадобится Windows API Code Pack.)

person Arithmomaniac    schedule 22.07.2013

Вот отличная статья, в которой описывается как сделать C# эквивалент этого JavaScript.

string result = DisplayInEnglish("Олъга Виктровна Василенко");
person Zhivko Kabaivanov    schedule 03.05.2017

Используйте этот метод. Просто передайте кириллическое слово, содержащее строку, и этот метод вернет латинско-английскую строку, соответствующую кириллической строке.

public static string GetLatinCodeFromCyrillic(string str)
    {

        str = str.Replace("б", "b");
        str = str.Replace("Б", "B");

        str = str.Replace("в", "v");
        str = str.Replace("В", "V");

        str = str.Replace("г", "h");
        str = str.Replace("Г", "H");

        str = str.Replace("ґ", "g");
        str = str.Replace("Ґ", "G");

        str = str.Replace("д", "d");
        str = str.Replace("Д", "D");

        str = str.Replace("є", "ye");
        str = str.Replace("Э", "Ye");

        str = str.Replace("ж", "zh");
        str = str.Replace("Ж", "Zh");

        str = str.Replace("з", "z");
        str = str.Replace("З", "Z");

        str = str.Replace("и", "y");
        str = str.Replace("И", "Y");

        str = str.Replace("ї", "yi");
        str = str.Replace("Ї", "YI");

        str = str.Replace("й", "j");
        str = str.Replace("Й", "J");

        str = str.Replace("к", "k");
        str = str.Replace("К", "K");

        str = str.Replace("л", "l");
        str = str.Replace("Л", "L");

        str = str.Replace("м", "m");
        str = str.Replace("М", "M");

        str = str.Replace("н", "n");
        str = str.Replace("Н", "N");

        str = str.Replace("п", "p");
        str = str.Replace("П", "P");

        str = str.Replace("р", "r");
        str = str.Replace("Р", "R");

        str = str.Replace("с", "s");
        str = str.Replace("С", "S");

        str = str.Replace("ч", "ch");
        str = str.Replace("Ч", "CH");

        str = str.Replace("ш", "sh");
        str = str.Replace("Щ", "SHH");

        str = str.Replace("ю", "yu");
        str = str.Replace("Ю", "YU");

        str = str.Replace("Я", "YA");
        str = str.Replace("я", "ya");

        str = str.Replace('ь', '"');
        str = str.Replace("Ь", "");

        str = str.Replace('т', 't');
        str = str.Replace("Т", "T");

        str = str.Replace('ц', 'c');
        str = str.Replace("Ц", "C");

        str = str.Replace('о', 'o');
        str = str.Replace("О", "O");

        str = str.Replace('е', 'e');
        str = str.Replace("Е", "E");

        str = str.Replace('а', 'a');
        str = str.Replace("А", "A");

        str = str.Replace('ф', 'f');
        str = str.Replace("Ф", "F");

        str = str.Replace('і', 'i');
        str = str.Replace("І", "I");

        str = str.Replace('У', 'U');
        str = str.Replace("у", "u");

        str = str.Replace('х', 'x');
        str = str.Replace("Х", "X");
        return str;
    }
person Pritesh    schedule 27.04.2012
comment
У вас неправильная таблица транслитерации, например. г никогда не заменяется на h, и на y и так далее. - person Sergey Glotov; 27.04.2012

person    schedule
comment
Давайте создадим 66*(количество символов) строк... хорошо. - person hazzik; 24.01.2015