From ed297b6594a66d8af590e187680056a9b7ff6b49 Mon Sep 17 00:00:00 2001 From: NeonXP Date: Wed, 27 Nov 2013 04:06:49 +0400 Subject: first commit --- src/NXP/Stemmer.php | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/NXP/Stemmer.php (limited to 'src/NXP') diff --git a/src/NXP/Stemmer.php b/src/NXP/Stemmer.php new file mode 100644 index 0000000..03b159b --- /dev/null +++ b/src/NXP/Stemmer.php @@ -0,0 +1,138 @@ +word = $word; + $this->findRegions(); + //Шаг 1 + //Найти окончание PERFECTIVE GERUND. Если оно существует – удалить его и завершить этот шаг. + if (!$this->removeEndings($this->regexPerfectiveGerunds, $this->RV)) { + //Иначе, удаляем окончание REFLEXIVE (если оно существует). + $this->removeEndings($this->regexReflexives, $this->RV); + //Затем в следующем порядке пробуем удалить окончания: ADJECTIVAL, VERB, NOUN. Как только одно из них найдено – шаг завершается. + if (!($this->removeEndings( + [ + $this->regexParticiple[0] . $this->regexAdjective, + $this->regexParticiple[1] . $this->regexAdjective + ], + $this->RV + ) || $this->removeEndings($this->regexAdjective, $this->RV)) + ) { + if (!$this->removeEndings($this->regexVerb, $this->RV)) { + $this->removeEndings($this->regexNoun, $this->RV); + } + } + } + //Шаг 2 + //Если слово оканчивается на и – удаляем и. + $this->removeEndings($this->regexI, $this->RV); + //Шаг 3 + //Если в R2 найдется окончание DERIVATIONAL – удаляем его. + $this->removeEndings($this->regexDerivational, $this->R2); + //Шаг 4 + //Возможен один из трех вариантов: + //Если слово оканчивается на нн – удаляем последнюю букву. + if ($this->removeEndings($this->regexNN, $this->RV)) { + $this->word .= 'н'; + } + //Если слово оканчивается на SUPERLATIVE – удаляем его и снова удаляем последнюю букву, если слово оканчивается на нн. + $this->removeEndings($this->regexSuperlative, $this->RV); + //Если слово оканчивается на ь – удаляем его. + $this->removeEndings($this->regexSoftSign, $this->RV); + + return $this->word; + } + + public function removeEndings($regex, $region) + { + $prefix = mb_substr($this->word, 0, $region, 'utf8'); + $word = mb_substr($this->word, $region, null, 'utf8'); + if (is_array($regex)) { + if (preg_match('/.+[а|я]' . $regex[0] . '/u', $word)) { + $this->word = $prefix . preg_replace('/' . $regex[0] . '/u', '', $word); + return true; + } + $regex = $regex[1]; + } + if (preg_match('/.+' . $regex . '/u', $word)) { + $this->word = $prefix . preg_replace('/' . $regex . '/u', '', $word); + return true; + } + + return false; + } + + private function findRegions() + { + $state = 0; + for ($i = 1; $i < mb_strlen($this->word, 'utf8'); $i++) { + $prevChar = mb_substr($this->word, $i - 1, 1, 'utf8'); + $char = mb_substr($this->word, $i, 1, 'utf8'); + switch ($state) { + case 0: + if ($this->isVowel($char)) { + $this->RV = $i + 1; + $state = 1; + } + break; + case 1: + if ($this->isVowel($prevChar) && !$this->isVowel($char)) { + $this->R1 = $i + 1; + $state = 2; + } + break; + case 2: + if ($this->isVowel($prevChar) && !$this->isVowel($char)) { + $this->R2 = $i + 1; + return; + } + break; + } + } + } + + private function isVowel($char) + { + return (strpos($this->vowel, $char) !== false); + } +} \ No newline at end of file -- cgit v1.2.3