Склонение русских числительных

В старом блоге была опубликована одноименная заметка, которая, несмотря на gettext и прочие аналогичные инструменты, до сих пор остается популярной. Это не может не удивлять, конечно.

Алгоритм, описанный в ней, содержал небольшую ошибку, ввиду чего не всегда определялась правильная форма слова. Но в комментариях подсказали ссылку, по которой можно было видеть огромный список формул определения формы, в том числе и для русского языка. Ниже предлагаю небольшую теоретическую выдержку из старой заметки и новый вариант алгоритма.




Существует три возможных варианта склонения имени существительного по числу:

  • Единственное число (один предмет)
  • Множественное двойственное число (2 предмета, пара)
  • Множественное число (более двух)

Первые и третий варианты знакомы всем. Двойственное число может у вызывать удивление, но оно существует, во всяком случае, ранее существовало и оговаривалось грамматически. Двойственное число является одним из видов множественного, хотя сейчас не принято делать такого разделения. Данная форма давно исчезла из русского языка.

Изначально такая форма была популярна за счет того, что не так часто приходилось вести счет большими величинами. Использовалась для обозначения двух предметов или предметов, которые имеют пару априори, например, части тела. Но, из русского языка (древнерусского) двойственное число стало исчезать еще в XIII веке.

Двойственное число было или есть во многих языках. Арабский язык не утратил этой формы по сей день. Не могу говорить о диалектах, но в классическом арабском язык эта форма активно используется.

Алгоритм сформирован по формуле:

plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)

Функция и пример вызова:

/**
 * 
 * @param int $n
 * @param string|array $s
 * @return string
 */
function getWordForm($n, $s) {
    if (!is_array($s)) {
        $forms = explode(',', $s);
    } else {
        $forms = $s;
    }

    if (($n % 10 == 1) && ($n % 100 != 11)) {
        $return = $forms[0];
    } elseif (($n % 10 >= 2) && ($n %10 <= 4)  && ($n % 100 < 10 || $n % 100 >= 20)) {
        $return = $forms[1];
    } else {
        $return = $forms[2];
    }

    return trim($return);
}

echo getWordForm(110, 'книга, книги, книг');

Комментарии (2)

  1. Иван

    «…
    • Множественное двойственное число (2 предмета, пара)
    …»
    Не 2 предмета, а от 2 до 4, причём даже плюс N десястков ─ просто если в конце 2, 3 или 4, кроме чисел где в конце 12, 13 или 14. (Ну и то же самое насчёт 1 ─ тоже в каждом десятке правило повторяется, кроме когда 11.)
    Поэтому и формула такая мудрёная.

    1 косяк
    2/3/4/22/../24/32/../34/../.. косяка
    5/6/../12/13/14/../.. косяков

    А в коде опечатка: на 11 строке
    >> $form = $s;
    , а надо
    >> $forms = $s;
    (буква s у $forms)

Добавить комментарий для Иван Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *