Skip to content

Instantly share code, notes, and snippets.

@insideone
Last active May 15, 2016 13:20
Show Gist options
  • Save insideone/7cc831acb51e4e0b1dccd6b05377ffa2 to your computer and use it in GitHub Desktop.
Save insideone/7cc831acb51e4e0b1dccd6b05377ffa2 to your computer and use it in GitHub Desktop.
PHP: Стеммер на базе алгоритма Портера, определение основы слова
<?php
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');
$word = 'точный';
Stem::word($word);
echo $word;
<?php
//
//
// Porter's Stemming inside edition v. 1.0
// thx: Vovan-VE
//
define('RVRE', '/^((?:пере|обез|обес|недо|пред|противо)*.*?[аеиоуыэюя])(.*)$/u');
define('PERFECTIVEGROUND', '/(ив|ивши|ившись|ыв|ывши|ывшись|вшись|авший|авшое|авшись|явшись|авши|явши)$/u');
define('REFLEXIVE', '/(ь?с[яь])$/u');
define('ADJECTIVE', '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/u');
define('PARTICIPLE', '/((ивш|ывш|ущ|ющ|ующ)|((?<=[ая])(ем|нн|вш|ущ|ющ|щ)))$/u');
define('VERB', '/(ала|али|ат|ать|ают|еем|еет|еете|еешь|ей|ейте|ели|ело|ем|ен|ена|ено|ены|ет|ете|еть|еут|еуют|ешь|еют|ийте|ил|ила|или|ило|им|ит|ите|ить|ишь|йте|ла|ли|ло|на|нно|но|ны|ует|уй|уйте|ут|уть|ую|уют|ыл|ыла|ыли|ыло|ым|ыт|ыть|ьем|ю|ют|яла|ят|ять)$/u');
define('NOUN', '/(?<=.{1})(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$/u');
define('DERIVATIONAL', '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/u');
define('ADVERB_SUFFIX', '/(жды|то|либо|нибудь|учи|ючи)$/u');
define('NOUN_SUFFIX', '/(?<=.{1})(ыг|чук|тор|тух|тел|тя|ств|ор|ер|ила|еныш|оня|онок|енок|онер|ь|онал|омец|овщик|евщик|овик|евик|овец|анист|нец|елец|алец|ан|ак|итянин|итор|ител|етик|енник|еник|енец|енек|ельщик|елин|аче|атик|ата|ат|анец|янец|анек|альщик|ал|аик|авк|явк|авец|овн|ович|евич|ичн|ич|ех|ышн|мейстер|ариус|уг|юг|уган|ук|юк|ул|ун|юн|ур|юр|ург|урк|ус|юс|ут|ют|утк|ютк|ух|юх|юш|уш|атор|ар|яр|яг|аг|льниц|лк|лиц|ис|ичк|ин|ын|ильщиц|ильщик|есс|ениц|ачк|ячк|анк|янк|арк|ярк|енц|изац|икац|антк|ент|янт|ант|истк|етк|атк|ир|ан|ян|анин|янин|ач|ен|ет|еств|ест|ец|изм|изн|ик|ник|ист|аист|тел|их|иц|ниц|овк|овщиц|евщиц|отк|льник|льщик|льщиц|ун|чик|щиц|чиц|щик|еньк|оньк|енк|онк|аш|яш|евт|ашк|ищ|инк|очк|ушк|юшк|ышк|ишк|очек|ечк|ушек|ышек|ыш|чонок|ок|чак|фоб)$/u');
define('ADJECTIVE_SUFFIX', '/(?<=.{1})(тор|тух|тель|тяй|онер|ь|ион|онал|нич|ийн|ышк|ишк|итянин|итор|итель|ир|ент|елин|евт|иче|ач|атель|тель|тел|атор|ярн|еств|арн|ионн|енц|изац|икац|абельн|арн|уозн|озн|ат|ичн|уальн|иальн|альн|ск|иров|ал|ель|ан|ян|аст|ев|ов|еват|оват|ен|енн|енск|лив|чив|ив|ин|овит|ит|шн|тельн|уч|чат|еньк|оньк|ехоньк|оханьк|ешеньк|ошеньк|ивн)$/u');
define('VERB_SUFFIX', '/(?<=.{1})(тя|ка|ева|ова|ыва|ива|нича|ну|ствова|ть|ти|ирова|ф)$/u'); // ф - "-фил" bugfix
class Stem
{
public static $LowerMode = FALSE;
public static $RV = '';
private static function clear($pattern)
{
self::$RV = preg_replace($pattern, '', self::$RV, -1, $count);
return $count;
}
public static function word($word)
{
if ( self::$LowerMode ) $word = mb_strtolower($word);
$word = preg_replace('/ё/u', 'е', $word);
if ( !preg_match(RVRE, $word, $word_parts) ) return;
self::$RV = $word_parts[2];
$start = $word_parts[1];
// echo 'Редактируем: ' . self::$RV . '';
if (!self::clear(PERFECTIVEGROUND)) // Причастие совершенного вида
{
self::clear(REFLEXIVE); // Возвратное (сь, ся)
if (self::clear(ADJECTIVE)) // Прилагательное
{
while(self::clear(ADJECTIVE_SUFFIX));
self::clear(PARTICIPLE); // Причастие
}
else
{
if ( !self::clear(ADVERB_SUFFIX) ) // Наречие
{
if (self::clear(VERB)) // Глагол
{
while(self::clear(VERB_SUFFIX));
}
else
{
self::clear(NOUN); // Существительное
while(self::clear(NOUN_SUFFIX));
}
}
}
}
self::clear('/и$/u');
if ( preg_match(DERIVATIONAL, self::$RV) ) // Словообразующее
self::clear('/ость?$/u');
if (!self::clear('/ь$/u'))
{
self::clear('/ейше?/u');
self::clear('/альн/u');
self::$RV = preg_replace('/нн$/u', 'н', self::$RV);
}
$ret = $start.self::$RV;
$word = (mb_strlen($ret) < 3)?mb_substr($word, 0, 3):$ret;
self::$RV = '';
return $word;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment