/** * Українські жіночі імена, що в називному відмінку однини закінчуються на приголосний, * відмінюються як відповідні іменники ІІІ відміни * @return boolean true - якщо було задіяно правило з переліку, false - якщо правило не знайдено */ protected function womanRule2() { if ($this->in($this->Last(1), $this->consonant . 'ь')) { $osnova = $this->getOsnova($this->workingWord); $apostrof = ''; $duplicate = ''; $osLast = NCLStr::substr($osnova, -1, 1); $osBeforeLast = NCLStr::substr($osnova, -2, 1); //Чи треба ставити апостроф if ($this->in($osLast, 'мвпбф') and $this->in($osBeforeLast, $this->vowels)) { $apostrof = '’'; } //Чи треба подвоювати if ($this->in($osLast, 'дтзсцлн')) { $duplicate = $osLast; } //Відмінюємо if ($this->Last(1) == 'ь') { $this->wordForms($osnova, array('і', 'і', 'ь', $duplicate . $apostrof . 'ю', 'і', 'е')); $this->Rule(201); return true; } else { $this->wordForms($osnova, array('і', 'і', '', $duplicate . $apostrof . 'ю', 'і', 'е')); $this->Rule(202); return true; } } return false; }
/** * Идетифицирует слово определяе имя это, или фамилия, или отчество * - <b>N</b> - имя * - <b>S</b> - фамилия * - <b>F</b> - отчество * @param NCLNameCaseWord $word обьект класса слов, который необходимо идентифицировать */ protected function detectNamePart(NCLNameCaseWord $word) { $namepart = $word->getWord(); $length = NCLStr::strlen($namepart); $this->setWorkingWord($namepart); //Считаем вероятность $first = 0; $second = 0; $father = 0; //если смахивает на отчество if ($this->in($this->Last(3), array('вна', 'чна', 'вич', 'ьич'))) { $father += 3; } if ($this->in($this->Last(2), array('ша'))) { $first += 0.5; } /** * буквы на которые никогда не закнчиваются имена */ if ($this->in($this->Last(1), 'еёжхцочшщъыэю')) { $second += 0.3; } /** * Используем массив характерных окончаний */ if (isset($this->splitSecondExclude[$this->Last(2, 1)])) { if (!$this->in($this->Last(1), $this->splitSecondExclude[$this->Last(2, 1)])) { $second += 0.4; } } /** * Сохкращенные ласкательные имена типя Аня Галя и.т.д. */ if ($this->Last(1) == 'я' and $this->in($this->Last(3, 1), $this->vowels)) { $first += 0.5; } /** * Не бывает имет с такими предпоследними буквами */ if ($this->in($this->Last(2, 1), 'жчщъэю')) { $second += 0.3; } /** * Слова на мягкий знак. Существует очень мало имен на мягкий знак. Все остальное фамилии */ if ($this->Last(1) == 'ь') { /** * Имена типа нинЕЛь адЕЛь асЕЛь */ if ($this->Last(3, 2) == 'ел') { $first += 0.7; } elseif ($this->inNames($namepart, array('Лазарь', 'Игорь', 'Любовь'))) { $first += 10; } else { $second += 0.3; } } elseif ($this->in($this->Last(1), $this->consonant . 'ь') and $this->in($this->Last(2, 1), $this->consonant . 'ь')) { /** * Практически все кроме тех которые оканчиваются на следующие буквы */ if (!$this->in($this->Last(2), array('др', 'кт', 'лл', 'пп', 'рд', 'рк', 'рп', 'рт', 'тр'))) { $second += 0.25; } } /** * Слова, которые заканчиваются на тин */ if ($this->Last(3) == 'тин' and $this->in($this->Last(4, 1), 'нст')) { $first += 0.5; } //Исключения if ($this->inNames($namepart, array('Лев', 'Яков', 'Вова', 'Маша', 'Ольга', 'Еремей', 'Исак', 'Исаак', 'Ева', 'Ирина', 'Элькин', 'Мерлин'))) { $first += 10; } /** * Фамилии которые заканчиваются на -ли кроме тех что типа натАли и.т.д. */ if ($this->Last(2) == 'ли' and $this->Last(3, 1) != 'а') { $second += 0.4; } /** * Фамилии на -як кроме тех что типа Касьян Куприян + Ян и.т.д. */ if ($this->Last(2) == 'ян' and $length > 2 and !$this->in($this->Last(3, 1), 'ьи')) { $second += 0.4; } /** * Фамилии на -ур кроме имен Артур Тимур */ if ($this->Last(2) == 'ур') { if (!$this->inNames($namepart, array('Артур', 'Тимур'))) { $second += 0.4; } } /** * Разбор ласкательных имен на -ик */ if ($this->Last(2) == 'ик') { /** * Ласкательные буквы перед ик */ if ($this->in($this->Last(3, 1), 'лшхд')) { $first += 0.3; } else { $second += 0.4; } } /** * Разбор имен и фамилий, который заканчиваются на ина */ if ($this->Last(3) == 'ина') { /** * Все похожие на Катерина и Кристина */ if ($this->in($this->Last(7), array('атерина', 'ристина'))) { $first += 10; } elseif ($this->inNames($namepart, array('Мальвина', 'Антонина', 'Альбина', 'Агриппина', 'Фаина', 'Карина', 'Марина', 'Валентина', 'Калина', 'Аделина', 'Алина', 'Ангелина', 'Галина', 'Каролина', 'Павлина', 'Полина', 'Элина', 'Мина', 'Нина'))) { $first += 10; } else { $second += 0.4; } } /** * Имена типа Николай */ if ($this->Last(4) == 'олай') { $first += 0.6; } /** * Фамильные окончания */ if ($this->in($this->Last(2), array('ов', 'ин', 'ев', 'ёв', 'ый', 'ын', 'ой', 'ук', 'як', 'ца', 'ун', 'ок', 'ая', 'ёк', 'ив', 'ус', 'ак', 'яр', 'уз', 'ах', 'ай'))) { $second += 0.4; } if ($this->in($this->Last(3), array('ова', 'ева', 'ёва', 'ына', 'шен', 'мей', 'вка', 'шир', 'бан', 'чий', 'кий', 'бей', 'чан', 'ган', 'ким', 'кан', 'мар', 'лис'))) { $second += 0.4; } if ($this->in($this->Last(4), array('шена'))) { $second += 0.4; } $max = max(array($first, $second, $father)); if ($first == $max) { $word->setNamePart('N'); } elseif ($second == $max) { $word->setNamePart('S'); } else { $word->setNamePart('F'); } }
/** * Склоняет текущие слова в падеж <var>$caseNum</var> и форматирует слово по шаблону <var>$format</var> * <b>Формат:</b> * - S - Фамилия * - N - Имя * - F - Отчество * @param string $format строка с форматом * @return string строка в нужном падеже */ public function getFormatted($caseNum = 0, $format = "S N F") { $this->AllWordCases(); //Если не указан падеж используем другую функцию if ($caseNum === null) { return $this->getFormattedArray($format); } elseif (is_array($format)) { return $this->getFormattedHard($caseNum, $format); } else { $length = NCLStr::strlen($format); $result = ""; for ($i = 0; $i < $length; $i++) { $symbol = NCLStr::substr($format, $i, 1); if ($symbol == 'S') { $result .= $this->getSecondNameCase($caseNum); } elseif ($symbol == 'N') { $result .= $this->getFirstNameCase($caseNum); } elseif ($symbol == 'F') { $result .= $this->getFatherNameCase($caseNum); } else { $result .= $symbol; } } return $result; } }
/** * Превращает строку в массив букв * @param string $phrase строка * @return array массив букв */ static function splitLetters($phrase) { $resultArr = array(); $stop = NCLStr::strlen($phrase); for ($idx = 0; $idx < $stop; $idx++) { $resultArr[] = NCLStr::substr($phrase, $idx, 1); } return $resultArr; }
/** * Возвращает все падежи слова в начальную маску: * - x - маленькая буква * - X - больная буква */ private function returnMask() { if ($this->isUpperCase) { foreach ($this->NameCases as $index => $case) { $this->NameCases[$index] = NCLStr::strtoupper($this->NameCases[$index]); } } else { $splitedMask = $this->letterMask; $maskLength = count($splitedMask); foreach ($this->NameCases as $index => $case) { $caseLength = NCLStr::strlen($case); $max = min(array($caseLength, $maskLength)); $this->NameCases[$index] = ''; for ($letterIndex = 0; $letterIndex < $max; $letterIndex++) { $letter = NCLStr::substr($case, $letterIndex, 1); if ($splitedMask[$letterIndex] == 'X') { $letter = NCLStr::strtoupper($letter); } $this->NameCases[$index] .= $letter; } $this->NameCases[$index] .= NCLStr::substr($case, $max, $caseLength - $maskLength); } } }