Last active
May 15, 2016 13:20
-
-
Save insideone/7cc831acb51e4e0b1dccd6b05377ffa2 to your computer and use it in GitHub Desktop.
PHP: Стеммер на базе алгоритма Портера, определение основы слова
This file contains hidden or 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
<?php | |
mb_internal_encoding('UTF-8'); | |
mb_regex_encoding('UTF-8'); | |
$word = 'точный'; | |
Stem::word($word); | |
echo $word; |
This file contains hidden or 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
<?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