Freika
@Freika
Senior Ruby on Rails developer

Как максимально грамотно и человечно разбивать слова на слоги?

Возникла необходимость разбивать слова на слоги, максимально грамотно и человечно. Не смог найти готового решения, и даже алгоритм толком себе не представляю, поэтому обращаюсь к вам: возможно, вы знаете сервис/скрипт/алгоритм, по которому можно разбивать слова на слоги? Был бы очень благодарен за любую помощь.
Языки, которые понимаю: php, js. Это на случай, если есть готовые скрипты, возможно, что-то допилил бы.
  • Вопрос задан
  • 7853 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
  • Слог – это фонетически значимая единица. Из слогов состоят фонетические слова.
  • В русском языке слогообразующими являются гласные звуки.
  • Каждый слог в русском языке может содержать не более одного гласного звука.
  • Один гласный звук, даже если рядом с ним нет согласных, тоже является отдельным фонетическим слогом. Например: а-ри-я.
  • Слоги в русском языке делятся на два типа:
    • открытые слоги, оканчивающиеся гласным звуком;
    • закрытые слоги – они оканчиваются согласным звуком.
  • Большинство слогов являются открытыми. Они могут состоять из одного гласного звука, оканчиваться им.
  • Чтобы определить, какой перед вами слог, открытый или закрытый, вам понадобится рассмотреть согласные звуки, которые окружают гласные звуки. Закрытые слоги образуются в следующих случаях:
    • чаще всего закрытый слог находится в конце слова, поскольку оно оканчивается согласным звуком: ка-ток;
    • слово может состоять из одного закрытого слога, так как в нём есть только один гласный звук, а оканчивается оно согласным: стол;
    • когда звуки «м», «р», «л», «н» находятся в середине слова, а за ними следуют глухие согласные, линия слогоделения проходит между согласными звуками – перед вами закрытый слог: лам-па;
    • если в слове есть звук «й», а за ним следует согласный, данное слово также содержит закрытый слог, который оканчивается на «й»: гай-ка.
  • В прочих случаях слог в середине или начале слова будет открытым.
  • Открытый слог оканчивается гласным звуком. Все следующие за ним согласные звуки, независимо от их количества, относятся ко второму слогу. Например: ко-шка.
  • Мы произносим двойные согласный как один звук, поскольку относим их к одному слогу, но с большей продолжительностью. Например: со-нник.
Запомните очень важный момент: фонетический слог – это не та часть слова, которую можно переносить на другую строчку. При делении слова для переноса нужно учитывать совершенно другие характеристики: морфологические особенности языковой единицы, количество морфем.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@personaljs
Взято отсюда:forum.vingrad.ru/forum/s/f63ccda5b94563fc1e1c1ab01...
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
  <title>Test</title>
  <script language="javascript">
    var vowel  = new String ('аеёиоуыэюя');                     // Гласные буквы
    var voiced = new String ('бвгджзлмнрхцчшщ');       // Звонкие и шипящие согласные
    var deaf   = new String ('кпстф');                             // Глухие согласные
    var brief  = new String ('й');                                      // Й
    var other  = new String ('ьъ');                                  // Другие
    var cons   = new String ('бвгджзйклмнпрстфхцчшщ'); // Все согласные
        // Валидация правильности введенной строки
        function validateString (s) {
       // Поленился делать :)
       return s;
        } // function validateString (s)
    // Есть ли в строке гласные?
    function isNotLastSep (remainStr) {
       var is = false;
       for (var i = 0; i < remainStr.length; i++) {
          if (vowel.indexOf (remainStr.substr (i, 1)) != -1) { is = true; break; }
       } // for (var i = 0; i < remainStr - 1; i++)
       return is;
    } // function isLastSep (remainStr)
    // Собственно функция разбиения слова на слоги
    function getSeparatedString (s) {
       // Добавляем слог в массив и начинаем новый слог
       function addSep () {
          sepArr.push (tmpS);
          tmpS = '';
       } // function addSep ()
       s = validateString (s);
       var tmpL   = new String ();  // Текущий символ
       var tmpS   = new String ();  // Текущий слог
       var sepArr = new Array ();   // Массив слогов
       for (var i = 0; i < s.length; i++) {
          tmpL = s.substr (i, 1);
          tmpS += tmpL;
          // Проверка на признаки конца слогов
          // если буква равна 'й' и она не первая и не последняя и это не последний слог
          if (
            (i != 0) && 
            (i != s.length -1) && 
            (brief.indexOf (tmpL) != -1) &&
            (isNotLastSep (s.substr (i+1, s.length-i+1)))
          ) { addSep (); continue; }
          // если текущая гласная и следующая тоже гласная
          if (
             (i < s.length - 1) && 
             (vowel.indexOf (tmpL) != -1) && 
             (vowel.indexOf (s.substr (i+1, 1)) != -1)
           ) { addSep (); continue; }
          // если текущая гласная, следующая согласная, а после неё гласная
          if (
             (i < s.length - 2) && 
             (vowel.indexOf (tmpL) != -1) && 
             (cons.indexOf (s.substr (i+1, 1)) != -1) && 
             (vowel.indexOf (s.substr (i+2, 1)) != -1)
           ) { addSep (); continue; }
          // если текущая гласная, следующая глухая согласная, а после согласная и это не последний слог
          if (
             (i < s.length - 2) && 
             (vowel.indexOf (tmpL) != -1) && 
             (deaf.indexOf (s.substr (i+1, 1)) != -1) && 
             (cons.indexOf (s.substr (i+2, 1)) != -1) &&
             (isNotLastSep (s.substr (i+1, s.length-i+1)))
          ) { addSep (); continue; }
          // если текущая звонкая или шипящая согласная, перед ней гласная, следующая не гласная и не другая, и это не последний слог
          if (
             (i > 0) && 
             (i < s.length - 1) && 
             (voiced.indexOf (tmpL) != -1) && 
             (vowel.indexOf (s.substr (i-1, 1)) != -1) && 
             (vowel.indexOf (s.substr (i+1, 1)) == -1) && 
             (other.indexOf (s.substr (i+1, 1)) == -1) && 
             (isNotLastSep (s.substr (i+1, s.length-i+1)))
          ) { addSep (); continue; }  
          // если текущая другая, а следующая не гласная если это первый слог
          if (
             (i < s.length - 1) && 
             (other.indexOf (tmpL) != -1) &&
             ((vowel.indexOf (s.substr (i+1, 1)) == -1) || 
             (isNotLastSep (s.substr (0, i))))
          ) { addSep (); continue; } 
       } // for (var i = 0; i < s.length; i++)
       sepArr.push (tmpS);
       return sepArr.join('-');
    } // function getSeparatedString (s)
  </script>
 </head>
 <body>
 <form>
    <input type="text" size="30" name="fromString" value="">
    <input type="button" value="Go!" onClick="document.forms[0].elements[2].value = getSeparatedString (document.forms[0].elements[0].value);">
    <br>
    <input type="text" size="30" name="toString" value="">
 </form>
 </body>
</html>
Ответ написан
@DenBond
becon:
Скрипт не допилен. При отработки текста пробелы меняются на '- ' (тире пробел).
Ответ написан
Комментировать
rhrn
@rhrn
Сделал npm пакет syllables-ru
демо: https://rhrn.github.io/syllables-ru/
репо: https://github.com/rhrn/syllables-ru

Нужна обратная связь. Про баги пишите в issue
https://github.com/rhrn/syllables-ru/issues
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы