【问题标题】:How to transliterate Cyrillic to Latin text如何将西里尔文音译为拉丁文
【发布时间】:2009-12-03 18:24:28
【问题描述】:

我有一种方法可以将任何拉丁文本(例如英语、法语、德语、波兰语)转换成它的 slug 形式,

例如Alpha Bravo Charlie => alpha-bravo-charlie

但它不适用于西里尔文字(例如俄语),所以我想做的是将西里尔文字音译为拉丁字符,然后将其 slugify。

有没有人有办法进行这种音译?无论是通过实际来源还是图书馆。

我使用 C# 进行编码,因此可以使用 .NET 库。或者,如果你有非 C# 代码,我相信我可以转换它。

【问题讨论】:

    标签: c# .net transliteration


    【解决方案1】:

    您可以使用 .NET 开源 dll 库 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());
    }
    

    简单、快速、强大。如果您愿意,可以轻松扩展/修改音译表。

    【讨论】:

    • 错了。这将 Анастасия 音译为 Anastasiya,而不是 Anastasia。这看起来很可怕。似乎这个文件(en.wikipedia.org/wiki/BGN/PCGN_romanization_of_Russian)在特殊规定中是错误的。此外,您没有考虑特殊规定,UnidecodeSharpFork 将德语变音符号 (äöüÄÖÜ) 音译为 aouAOU 而不是 ae oe ue Ae Oe Ue。这就是我从赞成票改为反对票的原因。如果您使用罗马化库(或算法),请正确执行,或以其他方式声明您的算法不完整/有错误且尚未准备好投入生产。
    • 我使用这个解决方法: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("Anastasiya", "Anastasia"); str = str.Replace("iy", "i"); //返回 this.Name.Unidecode();返回str;
    • “如果你做一个罗马化图书馆”我没有。这只是简单的“将每个字母音译为英语/拉丁语”。它远非完美,但它适用于许多语言。例如dotabro.com/player/76561198060110736/madgaming-crio-j-jinmawang 我用它来链接“总比没有好”。
    • @DimaStefantsov 音译假定从一个脚本的字符到另一个脚本的字符一对一映射。将 'ä' 转换为 'a' 违反了这条规则,因为没有办法将文本唯一地转写回原文(现在有办法知道原文中的 'a' 代表什么字符)。有明确定义的音译标准,定义了特定书写系统的音译方式。即使您在西里尔文中有相同的单词,保加利亚语中的罗马拼写方式也会与塞尔维亚语中的不同。在不知道文本是哪种语言的情况下,您无法进行音译。
    • @DimaStefantsov(续)。我的观点是,你不应该声称你的图书馆没有音译。但我知道你使用的源库也声称,所以我想这是他们的原罪。要扩展您的库以涵盖音译,您需要为不同的语言(俄语、塞尔维亚语、希腊语等)提供单独的规则集 - 甚至为不同的音译标准提供单独的规则集(现代希腊语至少有 5 或 6 个不同的标准)。并提供一个语言ID(culture ID)作为音译的输入参数。
    【解决方案2】:
        public static string Translit(string str)
        {
            string[] lat_up = {"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[] lat_low = {"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[] rus_up = {"А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я"};
            string[] rus_low = { "а", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я"};
            for (int i = 0; i <= 32; i++)
            {
                str = str.Replace(rus_up[i],lat_up[i]);
                str = str.Replace(rus_low[i],lat_low[i]);              
            }
            return str;
        }
    

    【讨论】:

    • 让我们创建 66*(字符数)字符串...很好。
    【解决方案3】:

    你为什么不能只使用transliteration table 并制作一个小的正则表达式或子例程?

    【讨论】:

    • 嗯...结果可能比我想象的要简单。会试试的,谢谢。
    【解决方案4】:

    优化了Sarvar Nishonboev的答案,似乎是一个最简单的解决方案,没有与每次迭代重新创建字符串相关的不必要的复杂性:

    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("Проверочный текст");
    

    【讨论】:

    • 注意,如果源字符串中有拉丁字符,这段代码会抛出异常...
    【解决方案5】:

    检查此代码:

    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;
            }
        }
    }
    

    crylic 到拉丁语:

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

    拉丁文到cryllic

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

    【讨论】:

    • 让我们创建 66*(字符数)字符串...很好。
    【解决方案6】:

    您可以使用我的库进行音译:https://github.com/nick-buhro/Translit
    它也可以在NuGet 上找到。

    例子:

    var latin = Transliteration.CyrillicToLatin(
        "Предками данная мудрость народная!", 
        Language.Russian);
    
    Console.WriteLine(latin);   
    // Output: Predkami dannaya mudrost` narodnaya!
    

    【讨论】:

      【解决方案7】:

      Microsoft 有一个音译工具,其中包含一个您可以挂钩的 DLL(如果您要非个人使用它,则需要检查许可限制)。你可以在Dejan Vesić's blog post了解更多信息

      【讨论】:

        【解决方案8】:

        给未来的读者

        Windows 7+ 可以通过其Extended Linguistic Services 执行此操作。 (您需要 Windows API Code Pack 从 .NET 执行此操作)

        【讨论】:

          【解决方案9】:

          这里有一个很棒的 article,它描述了如何制作一个与 this JavaScript 等效的 C#。

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

          【讨论】:

            【解决方案10】:

            使用此方法只需传递您的西里尔单词包含字符串,此方法返回对应于西里尔字符串的拉丁英文字符串。

            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;
                }
            

            【讨论】:

            • 你有错误的音译表,例如г 永远不会被 h 取代,и 永远不会被 y 取代等等。
            猜你喜欢
            • 2013-04-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-19
            • 2021-03-13
            • 1970-01-01
            • 1970-01-01
            • 2012-06-09
            相关资源
            最近更新 更多