Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   Поиск из файла (https://javascript.ru/forum/server/70853-poisk-iz-fajjla.html)

Sonya 07.10.2017 13:04

Поиск из файла
 
Здравствуйте! Опять проблемы с поиском. С поиском заданных слов в файле разобралась в разных вариациях. Но никак не могу сообразить как сделать наоборот:
Есть текстовый файл в нем строки-словосочетания, есть заданное предложение, как сделать поиск совпадений не в файле, а из файла, именно в таком порядке, связанно это с тем, что заданное предложение может быть длинным, а словосочетания на порядок короче, поэтому вариант поиска предложения в файле не подходит. А поиск в предложении на наличие словосочетаний, то что нужно.
Как перебрать массив строк файла на предмет совпадения вхождений в предложении?

laimas 07.10.2017 13:31

Sonya,
есть готовые решения для этого, ищите в сети, подключайте и используйте. А вообще, что вы уперлись в файлы, есть БД, а в них есть полнотекстовый поиск, логику которого можно задавать.

Sonya 07.10.2017 13:40

С БД только начала разбираться. А готовых решений не нашла, поэтому и написала на форуме.

laimas 07.10.2017 15:55

Значит не можете конкретизировать свой поисковый запрос.

Если:

предложение - "А Б вгде Ж З"
словосочетания - "А Б", "Ж З"

то обходом в цикле массива словосочетаний ищем их в предложении.

Если:

предложение - "А Ж вгде З Б"
словосочетания - "А Б", "Ж З"

и тоже нужно найти, то тоже самое, но с добавлением логики поиска И/ИЛИ

Видимо у вас структуры управляющие/хранимые не очень удачно построены, что требуются такие затратные операции.

Sonya 08.10.2017 09:10

Никак не получается

laimas 08.10.2017 10:24

Покажите пример того что искать и в чем искать.

Sonya 08.10.2017 11:13

$search = 'поиск слов';
$lines = file('text.txt');
foreach($lines as $num_line => $line_value)
{
    if(strpos($line_value, $search) !== FALSE)
        echo "$num_line $line_value<br>";
}

Так я ищу словосочетание в текстовом файле text.txt. Содержание текстового файла:
поиск слов
поиск предложений
поиск слова
поисковик
поиск словечек
поиск словосочетаний
поиски словечек

Естественно, все находит, но никак не могу сделать, чтобы процесс был обратным, чтобы из файла искал при том, чтобы выводил и номера строк совпадений.

laimas 08.10.2017 11:24

Цитата:

Сообщение от Sonya
не могу сделать, чтобы процесс был обратным

Что это значит?

Если поиск, это есть точное сопоставление строк $search и $line_value, то не strpos($line_value, $search), а array_keys() с параметром поиска, цикл при этом не нужен.

Sonya 08.10.2017 11:38

Цитата:

Сообщение от laimas (Сообщение 466876)
Что это значит?

Поиск из файла text.txt в строке $search, т.к. её содержание может быть таким: "Осуществить поиск слов в тексте".

Sonya 08.10.2017 11:46

Цитата:

Сообщение от laimas (Сообщение 466876)
Если поиск, это есть точное сопоставление строк $search и $line_value, то не strpos($line_value, $search), а array_keys() с параметром поиска, цикл при этом не нужен.

Пробовала, но это мне больше подошло, а что с этим могут быть проблемы?

laimas 08.10.2017 12:04

Цитата:

Сообщение от Sonya
Пробовала, но это мне больше подошло

Я не знаю что означает ваш поиск, но если строго строка равна строке при поиске $search в text.txt, то как раз это и нужно. Проблем с вашим кодом тоже не будет, просто это лишнее. А вот Поиск из файла text.txt в строке $search, тут как раз и нужен цикл в котором элементы массива из text.txt ищутся в строке $search, и strpos($search, $line_value) нужен. Только нужен регистронезависимый поиск и в случае UTF соответствующая функция для работы с многобайтными строками. Из какой строки файла будет совпадение покажет та же $num_line.

Sonya 08.10.2017 12:13

Цитата:

Сообщение от laimas (Сообщение 466882)
Я не знаю что означает ваш поиск, но если строго строка равна строке при поиске $search в text.txt, то как раз это и нужно.

Насчет строго, надо чтобы находил и "поиск слова", и "поиск словечек", и
"поиск словосочетаний" при $search = "поиск слов".

Sonya 08.10.2017 12:19

Цитата:

Сообщение от laimas (Сообщение 466882)
А вот Поиск из файла text.txt в строке $search, тут как раз и нужен цикл в котором элементы массива из text.txt ищутся в строке $search, и strpos($search, $line_value) нужен. Только нужен регистронезависимый поиск и в случае UTF соответствующая функция для работы с многобайтными строками. Из какой строки файла будет совпадение покажет та же $num_line.

Понимаю, что нужен цикл, случай, как раз с UTF, не могу понять, как сделать.

Sonya 08.10.2017 12:54

Заведомо зная, что так не правильно, но тем не менее:
$search = 'поиск слов';
 
$lines = file('text.txt');
mb_internal_encoding("UTF-8");
foreach($lines as $num_line => $line_value)
{
    if(mb_stripos($search, $line_value) !== FALSE)
        echo "$num_line $line_value<br>";
}

Конечно же не получилось, но как тогда?

Sonya 08.10.2017 13:06

C trim($line_value) получилось.

laimas 08.10.2017 13:19

Цитата:

Сообщение от Sonya
надо чтобы находил и "поиск слова", и "поиск словечек", и
"поиск словосочетаний" при $search = "поиск слов".


В таком случае почитать это https://habrahabr.ru/post/115394/

Sonya 08.10.2017 13:32

Да, но приведенный мною изначально код, находит это и без этого. А так для поиска склонений, я использую это:
class Lingua_Stem_Ru
{
    private $VERSION = "0.02";
    private $unset_predlog = true;
    private $Stem_Caching = 0;
    private $Stem_Cache = array();
    private $VOWEL = '/аеиоуыэюя/u';
    private $PERFECTIVEGROUND = '/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/u';
    private $REFLEXIVE = '/(с[яь])$/u';
    private $ADJECTIVE = '/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|еых|ую|юю|ая|яя|ою|ею)$/u';
    private $PARTICIPLE = '/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/u';
    private $VERB = '/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ены|ить|ыть|ишь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$/u';
    private $NOUN = '/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|и|ы|ь|ию|ью|ю|ия|ья|я)$/u';
    private $RVRE = '/^(.*?[аеиоуыэюя])(.*)$/u';
    private $DERIVATIONAL = '/[^аеиоуыэюя][аеиоуыэюя]+[^аеиоуыэюя]+[аеиоуыэюя].*(?<=о)сть?$/u';
    private $PREDLOG = '/(^|\s)(и|для|в|на|под|из|с|по)(\s|$)/u';
    private function s(&$s, $re, $to) {
        $orig = $s;
        $s = preg_replace($re, $to, $s);
        return $orig !== $s;
    }
 
    private function m($s, $re) {
        return preg_match($re, $s);
    }
    public function stem_string($words) {
        $word=explode(' ',$words);
        for ($i=0;$i<count($word);$i++) {
            if ($this->unset_predlog === TRUE) $word[$i] = preg_replace($this->PREDLOG, '', $word[$i]);
            $word[$i]=$this->stem_word($word[$i]);
            if(empty($word[$i])) unset($word[$i]);
        }
        return implode(' ',$word); //if you need return array change on -> return $word;
    }
 
    private function stem_word($word) {
        mb_regex_encoding( 'UTF-8' );
        mb_internal_encoding( 'UTF-8' );
        $word = mb_strtolower($word);
        $word= str_ireplace('ё', 'е', $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;
    }
 
    private 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;
    }
 
    public function clear_stem_cache() {
        $this->Stem_Cache = array();
    }
}
 
$stemmer=new Lingua_Stem_Ru();
$words=$stemmer->stem_string($words);

laimas 08.10.2017 13:35

Цитата:

Сообщение от Sonya
но приведенный мною изначально код, находит это и без этого

Да, но только в том случае, если поисковое, это корень в словосочетаниях, иначе не получится.

Sonya 08.10.2017 13:44

Да, для той задачи где я использовала этот код, нужен был именно корень.
Здесь же я его привела, как пример, того что искать и в чем искать.
Огромное спасибо Вам за урок.

laimas 08.10.2017 13:49

Цитата:

Сообщение от Sonya
для той задачи где я использовала этот код, нужен был именно корень

Тогда как может быть в примере "слова" и "слово"? Поиск "слово" в приведенных сочетаниях найдет, ибо это корень, а вот в "словесный" уже нет, имеется ввиду strpos. А "слова" вообще ни в чем не найдет. Потребуются замены и подстановки.

Sonya 08.10.2017 14:18

Если я ищу словосочетание "поиск слов" приведенный в примере, то он найдет в словосочетании "поиск словесных выражений", т.к. корень "слов", также как и в "поиск слова", и "поиск слово".

laimas 08.10.2017 15:17

Цитата:

Сообщение от Sonya
Если я ищу словосочетание "поиск слов"

Это если так, но вы то описывали ранее из которого такого не следовало.

Работает? И слава богу.

Sonya 08.10.2017 15:27

Да, спасибо, работает!
Может мы о разных кодах говорим? Но с самого начало я указывала именно, что $search = 'поиск слов';

laimas 08.10.2017 16:25

Цитата:

Сообщение от Sonya
Может мы о разных кодах говорим?

Нет, я говорю о том что вами написано:

Насчет строго, надо чтобы находил и "поиск слова", и "поиск словечек", и
"поиск словосочетаний" при $search = "поиск слов".


А еще говорилось о том, что операция подразумевает и обратное, тогда поиск слова нельзя найти. От этого видимо недопонимание и путаница.

Sonya 08.10.2017 18:43

Наверное, все-таки Вы не так меня поняли, или я неправильно объяснила (что скорее всего). Код был приведен для примера (хотя он и рабочий), из которого я пыталась сделать обратный процесс. Но он никак не связан с той задачей, которую я пыталась решить. Просто от этого кода я отталкивалась.
То, что я писала: "Насчет строго, надо чтобы находил и "поиск слова", и "поиск словечек", и "поиск словосочетаний" при $search = "поиск слов"." - это к тому коду, и к той задачи, которая уже решена, но поскольку Вы написали, что это можно решить по другому, используя array_keys(), то в этом контексте и пошел разговор о том коде.


Часовой пояс GMT +3, время: 09:59.