A
A
Alexey Smirnov2016-03-17 20:58:23
.NET
Alexey Smirnov, 2016-03-17 20:58:23

How to determine all places in a word in which it is possible to transfer part of this word to another line, according to the rules of the Russian language?

Hello.
There is some arbitrary Russian-language word, for example:
Интернационализация
This word, according to the rules of the Russian language, can be transferred according to the following syllables:
Ин-тер-наци-она-лиза-ция - at least this is how Word transfers.
That is, transfers in this word can be carried out in 5 places.
I need to automatically determine in which places of a certain Russian word it is possible to transfer (parts of the word to another line according to the rules of the Russian language). That is, to determine after which letter in the account, from the very beginning of the word, you can transfer.
How can this be implemented?
PS Maybe there are some ready-made tools for this, for example in the .NET library, or in some third-party library?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexey Smirnov, 2016-03-18
@ERAFY

In general, I got the following class, which allows you to place dashes in places where words are wrapped according to the rules of the Russian language.
The class works on the basis of Christ's algorithm and is written in C#.
You can run the code below for execution with the line:
Perhaps someone will come in handy in the future.
-------------------------------------------------- -----

public static class PasteDashes
    {
        // Метод проверки, есть ли в строке гласные?
        private static bool isNotLastSep(string subStr)
        {
            string vowel = "аеёиоуыэюя";

            var b = false;
            for (var i = 0; i < subStr.Length; i++)
            {
                if (vowel.IndexOf(subStr.Substring(i, 1)) != -1)
                {
                    b = true;
                    break;
                }
            }
            return b;
        }


        // Метод разбиения слова на слоги
        private static List<string> addSeparator(string tmpS, List<string> sepList)
        {
            sepList.Add(tmpS);
            //tmpS = "";

            return sepList;
        }


        // Метод убирания знаков тире после первой буквы и перед последней (если там есть знаки тире)
        private static string ConnectFirstAndLastLettersToSyllables(string word)
        {
            if (word[1] == '-')
                word = word.Remove(1, 1);

            if (word[word.Length - 2] == '-')
                word = word.Remove(word.Length - 2, 1);

            return word;
        }



        //Основной метод работающий по алгоритму Христова
        public static string SeparateWord(string word)
        {
            string vowel = "аеёиоуыэюя";
            string voiced = "бвгджзлмнрхцчшщ";
            string deaf = "кпстф";
            string brief = "й";
            string other = "ьъ";
            string consonant = "бвгджзйклмнпрстфхцчшщ";

            string letter, syllable = "";
            var syllables = new List<string>();


            for (var i = 0; i < word.Length; i++)
            {
                letter = word.Substring(i, 1);
                syllable += letter;

                bool l;
                if (word.Length != i + 1)
                {
                    var k = word.Substring(i + 1, 1);
                    Regex rgx = new Regex("[А-Яа-я]");
                    l = rgx.IsMatch(k);
                }
                else
                    l = false;


                if (l)
                {
                    // Проверка на признаки конца слогов
                    // Если буква равна 'й' и она не первая и не последняя и это не последний слог
                    if (
                        (i != 0) &&
                        (i != word.Length - 1) &&
                        (brief.IndexOf(letter) != -1) &&
                        (isNotLastSep(word.Substring(i + 1)))
                        )
                    {
                        syllables = addSeparator(syllable, syllables);
                        syllable = "";
                        //continue;
                    }

                    // Если текущая гласная и следующая тоже гласная
                    // EDIT: этот блок необходим если задача - корректно разбить слово на фонетические слоги,
                    // и не нужен если задача - разбить слово на части, которые можно переносить
                    //if (
                    //    (i < word.Length - 1)
                    //    && (vowel.IndexOf(letter) != -1) &&
                    //    (vowel.IndexOf(word.Substring(i + 1, 1)) != -1)
                    //    )
                    //{
                    //    syllables = addSeparator(syllable, syllables);
                    //    syllable = "";
                    //    // continue;
                    //}

                    // Если текущая гласная, следующая согласная, а после неё гласная
                    if (
                        (i < word.Length - 2) &&
                        (vowel.IndexOf(letter) != -1) &&
                        (consonant.IndexOf(word.Substring(i + 1, 1)) != -1) &&
                        (vowel.IndexOf(word.Substring(i + 2, 1)) != -1)
                        )
                    {
                        syllables = addSeparator(syllable, syllables);
                        syllable = "";
                        // continue;
                    }

                    // Если текущая гласная, следующая глухая согласная, а после согласная и это не последний слог
                    if (
                        (i < word.Length - 2) &&
                        (vowel.IndexOf(letter) != -1) &&
                        (deaf.IndexOf(word.Substring(i + 1, 1)) != -1) &&
                        (consonant.IndexOf(word.Substring(i + 2, 1)) != -1) &&
                        (isNotLastSep(word.Substring(i + 1)))
                        )
                    {
                        syllables = addSeparator(syllable, syllables);
                        syllable = "";
                        // continue;
                    }

                    // Если текущая звонкая или шипящая согласная, перед ней гласная, следующая не гласная и не другая, и это не последний слог
                    if (
                        (i > 0) &&
                        (i < word.Length - 1) &&
                        (voiced.IndexOf(letter) != -1) &&
                        (vowel.IndexOf(word.Substring(i - 1, 1)) != -1) &&
                        (vowel.IndexOf(word.Substring(i + 1, 1)) == -1) &&
                        (other.IndexOf(word.Substring(i + 1, 1)) == -1) &&
                        (isNotLastSep(word.Substring(i + 1)))
                        )
                    {
                        syllables = addSeparator(syllable, syllables);
                        syllable = "";
                        // continue;
                    }

                    // Если текущая другая, а следующая не гласная если это первый слог
                    if (
                        (i < word.Length - 1) &&
                        (other.IndexOf(letter) != -1) &&
                        ((vowel.IndexOf(word.Substring(i + 1, 1)) == -1) ||
                        (isNotLastSep(word.Substring(0, i))))
                        )
                    {
                        syllables = addSeparator(syllable, syllables);
                        syllable = "";
                        //continue;
                    }
                }
            }
            syllables = addSeparator(syllable, syllables);

            string finalWord = string.Join("-", syllables);

            finalWord = ConnectFirstAndLastLettersToSyllables(finalWord);

            return finalWord;
        }
    }

S
Shetani, 2016-03-18
@Shetani

The Liang-Knuth algorithm for placing soft hyphens

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question