-
-
Save ddv88/8b8d9377d37eaf3e306dee716b79a082 to your computer and use it in GitHub Desktop.
Russian cities declension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static function declension(string $word) { | |
//Согласные | |
$consonants = ["б", "в", "г", "д", "ж", "з", "й", "к", "л", "м", "н", "п", "р", "с", "т", "ф", "х", "ц", "ч", "ш", "щ", "ь"]; | |
//Гласные | |
$vocal = ["а", "у", "о", "ы", "и", "э", "я", "ю", "ё", "е"]; | |
//Глухие согласные | |
$deafConsonants = ["п", "ф", "к", "т", "ш", "с", "х", "ц", "ч", "щ"]; | |
//Звонкие согласные | |
$voicedConsonants = ["б", "в", "г", "д", "ж", "з", "л", "м", "н", "р"]; | |
//Общие окончания | |
$endings = [ | |
"ий","ай","ая","ты","ей","ри","ды","ое","ец","ый","ны","ие","ые","бо","но","во","ть","ро","ор","ма","ау","ко","кт","ну","ян","ар","нь","ый","лы","ль", | |
"чи","ки","ой","ок","аы","ни" | |
]; | |
//Окончание при глухой согласной | |
$deafEndings = ["ий" => "ом", "ой" => "ом"]; | |
//Окончание при звонкой согласной | |
$voicedEndings = ["ий" => "ем", "ой" => "ое", "ец" => "це"]; | |
//Простые окончания | |
$regularEndings = [ | |
"ай" => "ае","ая" => "ой","ты" => "тах","ей" => "ее","ри" => "рях","ды" => "дах","лы" => "лах","ое" => "ом","ор" => "ору","ец" => "це","ый" => "ом", | |
"ны" => "нах","ие" => "их","ые" => "ых","ий" => "ом","ль" => "ле","нь" => "не","чи" => "чах","ки" => "ках","ок" => "ке","аы" => "ау","ни" => "нях" | |
]; | |
//Окончание при третьем гласном знаке | |
$vocalEndings = ["ень" => "не", "оби" => "би", "лец" => "льце", "очи" => "очи"]; | |
//Несклоняемые окончания | |
$noDeclension = ["ну", "бо", "но", "во", "ть", "ро", "ма", "ау", "ко", "кт", "ян", "ар", "ак", "ев", "ас", "ид", "он", "ыл", "сь"]; | |
//Проверяем сложное название или простое по наличию дефиса или пробела | |
preg_match("~(-на-|-|\s)~", $word, $delimiter) ? $word = explode($delimiter[0], $word) : null; | |
//Если сложно выполняем склонение для каждой части отдельно | |
if (is_array($word)) { | |
foreach ($word as $key => $value) { | |
//Получаем последний знак | |
$singleChar = mb_substr($value, -1); | |
//Определяем гласная или согласная | |
if (in_array($singleChar, $vocal)) {//Если гласная | |
//Получаем окончание из 2 знаков | |
$twoChars = mb_strtolower(mb_substr($value, -2)); | |
if (!in_array($twoChars, $noDeclension)) { | |
if (in_array($twoChars, $endings)) { | |
//Если окончание присутствует в массиве получаем третий знак | |
$thirdChar = mb_strtolower(mb_substr($value, -3, 1)); | |
//Если глухой | |
if (in_array($thirdChar, $deafConsonants)) { | |
if (array_key_exists($twoChars, $deafEndings)) { | |
$word[$key] = mb_substr($value, 0, -2) . $deafEndings[$twoChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
//Если звонкий | |
} elseif (in_array($thirdChar, $voicedConsonants)) { | |
if (array_key_exists($twoChars, $voicedEndings)) { | |
$word[$key] = mb_substr($value, 0, -2) . $voicedEndings[$twoChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
//Если третий символ гласный | |
} elseif (in_array($thirdChar, $vocal)) { | |
//Получаем окончание из 3 знаков | |
$threeChars = mb_substr($value, -3); | |
if (array_key_exists($threeChars, $vocalEndings)) { | |
$word[$key] = mb_substr($value, 0, -3) . $vocalEndings[$threeChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
//Или берем стандартное окнчание | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
} else { | |
$word[$key] = mb_substr($value, 0, -1) . "е"; | |
} | |
} | |
} | |
if (in_array($singleChar, $consonants)) {//Если согласная | |
//Получаем окончание из 2 знаков | |
$twoChars = mb_strtolower(mb_substr($value, -2)); | |
if (!in_array($twoChars, $noDeclension)) { | |
if (in_array($twoChars, $endings)) { | |
//Если окончание присутствует в массиве получаем третий знак | |
$thirdChar = mb_strtolower(mb_substr($value, -3, 1)); | |
if (in_array($thirdChar, $deafConsonants)) { | |
if (array_key_exists($twoChars, $deafEndings)) { | |
$word[$key] = mb_substr($value, 0, -2) . $deafEndings[$twoChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
//Если звонкий | |
} elseif (in_array($thirdChar, $voicedConsonants)) { | |
if (array_key_exists($twoChars, $voicedEndings)) { | |
$word[$key] = mb_substr($value, 0, -2) . $voicedEndings[$twoChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
} elseif (in_array($thirdChar, $vocal)) { | |
//Получаем окончание из 3 знаков | |
$threeChars = mb_substr($value, -3); | |
if (array_key_exists($threeChars, $vocalEndings)) { | |
$word[$key] = mb_substr($value, 0, -3) . $vocalEndings[$threeChars]; | |
} else { | |
$word[$key] = mb_substr($value, 0, -2) . $regularEndings[$twoChars]; | |
} | |
} | |
} else $word[$key] = "{$value}е"; | |
} | |
} | |
} | |
//Склеиваем обратно и возвращаем | |
return implode($delimiter[0], $word); | |
} | |
//Если навзание простое выполняем склонение в штатном режиме | |
$singleChar = mb_strtolower(mb_substr($word, -1)); | |
//Если гласная | |
if (in_array($singleChar, $vocal)) { | |
$twoChars = mb_strtolower(mb_substr($word, -2)); | |
if (!in_array($twoChars, $noDeclension)) { | |
if (in_array($twoChars, $endings)) { | |
//Если окончание присутствует в массиве получаем третий знак | |
$threeChars = mb_substr($word, -3); | |
if (in_array($threeChars, $vocalEndings)) { | |
return mb_substr($word, 0, -3) . $vocalEndings[$threeChars]; | |
} | |
return mb_substr($word, 0, -2) . $regularEndings[$twoChars]; | |
} | |
return mb_substr($word, 0, -1) . "е"; | |
} | |
return $word; | |
} | |
//Если согласная | |
if (in_array($singleChar, $consonants)) { | |
$twoChars = mb_strtolower(mb_substr($word, -2)); | |
if (!in_array($twoChars, $noDeclension)) { | |
if (in_array($twoChars, $endings)) { | |
//Если окончание присутствует в массиве получаем третий знак | |
$thirdChar = mb_strtolower(mb_substr($word, -3, 1)); | |
if (in_array($thirdChar, $deafConsonants)) { | |
if (array_key_exists($twoChars, $deafEndings)) { | |
return mb_substr($word, 0, -2) . $deafEndings[$twoChars]; | |
} else { | |
return mb_substr($word, 0, -2) . $regularEndings[$twoChars]; | |
} | |
//Если звонкий | |
} elseif (in_array($thirdChar, $voicedConsonants)) { | |
if (array_key_exists($twoChars, $voicedEndings)) { | |
return mb_substr($word, 0, -2) . $voicedEndings[$twoChars]; | |
} else { | |
return mb_substr($word, 0, -2) . $regularEndings[$twoChars]; | |
} | |
} | |
return mb_substr($word, 0, -2) . $regularEndings[$twoChars]; | |
} | |
} | |
return "{$word}е"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment