Определить корень слова. Трабла

Тема в разделе "PHP", создана пользователем phillip, 1 мар 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    Нарыл тут класс, определяет корень слова. Но что-то у меня не работает, не понимаю в чем дело. Может кто глянет? Вот так делаю:

    PHP:
    class Lingua_Stem_Ru
    {
    var 
    $VERSION "0.02";
    var 
    $Stem_Caching 0;
    var 
    $Stem_Cache = array();
    var 
    $VOWEL '/аеиоуыэюя/';
    var 
    $PERFECTIVEGROUND '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/';
    var 
    $REFLEXIVE '/(с[яь])$/';
    var 
    $ADJECTIVE '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|о го|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/';
    var 
    $PARTICIPLE '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/';
    var 
    $VERB '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им |ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|иш ь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь| нно)))$/';
    var 
    $NOUN '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий |й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|и я|ья|я)$/';
    var 
    $RVRE '/^(.*?[аеиоуыэюя])(.*)$/';
    var 
    $DERIVATIONAL '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/';

    function 
    s(&$s$re$to)
    {
    $orig $s;
    $s preg_replace($re$to$s);
    return 
    $orig !== $s;
    }

    function 
    m($s$re)
    {
    return 
    preg_match($re$s);
    }

    function 
    stem_word($word)
    {
    $word strtolower($word);
    $word strtr($word'ё''е');
    # Check against cache of stemmed words
    if ($this->Stem_Caching && isset($this->Stem_Cache[$word])) {
    return 
    $this->Stem_Cache[$word];
    }
    $stem $word;
    do {
    if (!
    preg_match($this->RVRE$word$p)) break;
    $start $p[1];
    $RV $p[2];
    if (!
    $RV) break;

    # Step 1
    if (!$this->s($RV$this->PERFECTIVEGROUND'')) {
    $this->s($RV$this->REFLEXIVE'');

    if (
    $this->s($RV$this->ADJECTIVE'')) {
    $this->s($RV$this->PARTICIPLE'');
    } else {
    if (!
    $this->s($RV$this->VERB''))
    $this->s($RV$this->NOUN'');
    }
    }

    # Step 2
    $this->s($RV'/и$/''');

    # Step 3
    if ($this->m($RV$this->DERIVATIONAL))
    $this->s($RV'/ость?$/''');

    # Step 4
    if (!$this->s($RV'/ь$/''')) {
    $this->s($RV'/ейше?/''');
    $this->s($RV'/нн$/''н');
    }

    $stem $start.$RV;
    } while(
    false);
    if (
    $this->Stem_Caching$this->Stem_Cache[$word] = $stem;
    return 
    $stem;
    }

    function 
    stem_caching($parm_ref)
    {
    $caching_level = @$parm_ref['-level'];
    if (
    $caching_level) {
    if (!
    $this->m($caching_level'/^[012]$/')) {
    die(
    __CLASS__ "::stem_caching() - Legal values are '0','1' or '2'. '$caching_level' is not a legal value");
    }
    $this->Stem_Caching $caching_level;
    }
    return 
    $this->Stem_Caching;
    }

    function 
    clear_stem_cache()
    {
    $this->Stem_Cache = array();
    }
    }

    $stemmer = new Lingua_Stem_Ru();
    echo 
    $stemmer->stem_word('крабовый');
     
  2. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Тупо скопипастил в фару, запустил - все работает.

    Проверь, в какой кодировке сохраняешь файл. Может у тебя не пашет из-за utf?
     
    phillip нравится это.
  3. phillip

    phillip

    Регистр.:
    4 сен 2007
    Сообщения:
    413
    Симпатии:
    15
    в .htaccess у меня стоит
    AddDefaultCharset UTF-8

    сам файл в кодировке UTF-8

    запускаю- вот что на выходе получаю:
    PHP:
    кЀабовЋ 
    :nezn:
     
  4. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Да, потому и не работает. Надо cp1251. И сам файл, и текст к нему (если будешь совать текст), и вывод.
     
    phillip нравится это.
  5. a_n_d_y

    a_n_d_y

    Регистр.:
    26 мар 2006
    Сообщения:
    465
    Симпатии:
    61
    Проблема в функции strtr - она не работает с utf, ну и поставить модификатор u для регулярок.
    Вот работающий вариант для UTF-8.
    PHP:
    header("Content-Type: text/html; charset=utf-8");
    class 
    Lingua_Stem_Ru
    {
        var 
    $VERSION "0.02";
        var 
    $Stem_Caching 0;
        var 
    $Stem_Cache = array();
        var 
    $VOWEL '/аеиоуыэюя/';
        var 
    $PERFECTIVEGROUND =
            
    '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/u';
        var 
    $REFLEXIVE '/(с[яь])$/u';
        var 
    $ADJECTIVE '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|о го|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/u';
        var 
    $PARTICIPLE '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/u';
        var 
    $VERB '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им |ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|иш ь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь| нно)))$/u';
        var 
    $NOUN '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий |й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|и я|ья|я)$/u';
        var 
    $RVRE '/^(.*?[аеиоуыэюя])(.*)$/u';
        var 
    $DERIVATIONAL '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/u';

        function 
    s(&$s$re$to)
        {
            
    $orig $s;
            
    $s preg_replace($re$to$s);
            return 
    $orig !== $s;
        }

        function 
    m($s$re)
        {
            return 
    preg_match($re$s);
        }

        function 
    stem_word($word)
        {
            
    $word mb_strtolower($word'UTF-8');
            
    $word preg_replace('/ё/u''е'$word);
            
    # Check against cache of stemmed words
            
    if ($this->Stem_Caching && isset($this->Stem_Cache[$word])) {
                return 
    $this->Stem_Cache[$word];
            }
            
    $stem $word;
            do {
                if (!
    preg_match($this->RVRE$word$p))
                    break;
                
    $start $p[1];
                
    $RV $p[2];
                if (!
    $RV)
                    break;

                
    # Step 1
                
    if (!$this->s($RV$this->PERFECTIVEGROUND'')) {
                    
    $this->s($RV$this->REFLEXIVE'');

                    if (
    $this->s($RV$this->ADJECTIVE'')) {
                        
    $this->s($RV$this->PARTICIPLE'');
                    } else {
                        if (!
    $this->s($RV$this->VERB''))
                            
    $this->s($RV$this->NOUN'');
                    }
                }

                
    # Step 2
                
    $this->s($RV'/и$/u''');

                
    # Step 3
                
    if ($this->m($RV$this->DERIVATIONAL))
                    
    $this->s($RV'/ость?$/u''');

                
    # Step 4
                
    if (!$this->s($RV'/ь$/u''')) {
                    
    $this->s($RV'/ейше?/u''');
                    
    $this->s($RV'/нн$/u''н');
                }

                
    $stem $start $RV;
            } while (
    false);
            if (
    $this->Stem_Caching)
                
    $this->Stem_Cache[$word] = $stem;
            return 
    $stem;
        }

        function 
    stem_caching($parm_ref)
        {
            
    $caching_level = @$parm_ref['-level'];
            if (
    $caching_level) {
                if (!
    $this->m($caching_level'/^[012]$/')) {
                    die(
    __class__ "::stem_caching() - Legal values are '0','1' or '2'. '$caching_level' is not a legal value");
                }
                
    $this->Stem_Caching $caching_level;
            }
            return 
    $this->Stem_Caching;
        }

        function 
    clear_stem_cache()
        {
            
    $this->Stem_Cache = array();
        }
    }

    $stemmer = new Lingua_Stem_Ru();
    echo 
    $stemmer->stem_word('крабовый');
    Добавлено через 1 минуту
    Не надо таких плясок с бубном, достаточно немного подумать и переписать под utf-8 ;)
     
    phillip нравится это.
  6. dandandan

    dandandan

    Регистр.:
    7 авг 2008
    Сообщения:
    996
    Симпатии:
    268
    есть интересный класс, который называетя phpMorphy как вариант можете попробовать воспользоваться им.
     
    phillip нравится это.
Статус темы:
Закрыта.