/**
  * Українські жіночі імена, що в називному відмінку однини закінчуються на приголосний, 
  * відмінюються як відповідні іменники ІІІ відміни
  * @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;
     }
 }
Exemple #4
0
 /**
  * Превращает строку в массив букв
  * @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);
         }
     }
 }