Hey guys. Не могу справиться с логикой.. PHP: <?php /* • apple banana – производит поиск на содержание по меньшей мере одно из этих слов. Т.е. мы тупо ищем в файле либо либо, либо другое и выводим "Нашли", а что нашли надо говорить? • +apple +juice – обязательно оба слова если нашли apple, но не нашли juice, то говорим что нихрена не нашли • +apple +juice – обязательно оба слова • +apple macintosh – обязательно apple, но не обязательно macintosh т.е. если в файле нету apple, но есть macintosh, то говорим ок, нашли • +apple -macintosh – обязетельно слово apple, не должно быть слова macintosh если нашли apple И нашли macintosh, то говорим что ничего не нашли • apple* – Поиск должен находить apple, apples, applesauce, и applet. любое наличие apple* выводим ОК • "some words" – Поиск по точной фразе вхождения. ок */ $template = '+apple +banana'; if (strpos($template, ' ')) { $a = explode(' ', $template); $file = file_get_contents('test.txt'); $find = array(); /* apple banana foreach ($a as $value) { if (preg_match("#[ \r\n\t]" . $value . '[ \r\n\t]#', $file, $s)) { $find = true; } }*/ foreach ($a as $key => $value) { if ($value[0] == '+') { $value = substr($value, 1); var_dump($value); if (preg_match("#[ \r\n\t]" . $value . '[ \r\n\t]#', $file, $s)) { $find[$key] = true; } else { $find[$key] = false; } } } } var_dump($find); В коде закомментирован пример для первого правила, когда найдено вхождение или apple или banana. Но дальше я не могу придумать для других правил, как все-таки проверять эти шаблоны..
Для шаблонов вида: +apple +banana +apple -banana +apple banana написал так: PHP: <?php $template = "+banana -apple"; $fileContent = 'banana apple'; $parts = explode(' ', $template); $validKeys = '+-'; $state = array(); $wordCount = count($parts); for ($i = 0; $i < $wordCount; $i++) { $key = $parts[$i]{0}; if (strpos($validKeys, $key) !== false) { $word = substr($parts[$i], 1); } else { $word = $parts[$i]; } $state[$i] = (boolean) preg_match("/\b{$word}\b/i", $fileContent); if ($key == '-') { $state[$i] = !$state[$i]; } } var_dump($state); в массиве $state хранятся состояния выполнения каждой части шаблона. Для наглядности можно представить в виде ассоциативного массива $state[$parts[$i]] = ...
А вообще идеи: Если использовать регулярки, то экранировать спецсимволы. Проверить на противоречия в правилах поиска и если есть, то выдать false. Например, +banana -banana Либо выделить уникальные слова. Сгруппировать правила при поиске, например, для +banana foo +bar -train preg_match('/\b(banana|foo|bar|train)\b/i', 'foo train bar', $m); и дальше парсить результат $m
Во втором посте не совсем то что надо.. результат в принципе получили, отлично. Но как теперь этот результат вернуть к одному true или false исходя из правила. Т.е. файл apple banana juice Правило: 1) apple banana вернет true 2) +apple +macintosh вернет false 3) +apple -banana вернет false
PHP: $result = true; for ($i = 0; $i < count($state); $i++) { $result &= $state[$i]; } var_dump($result); наверное, можно без цикла, но пока ничего другого. Или так: PHP: var_dump(array_sum($state) == count($state));
Блеать, логика опять нарушилась... PHP: $template = '+ПАУСТОВСКИЙ banananana'; $content = 'Константин Георгиевич ПАУСТОВСКИЙ (1892 1968) Революция, гражданская война, разруха, голод. Константин Паустовский был свидетелем исторических перемен —времени, когда '; $parts = explode(' ', $template); $validKeys = '+-'; $state = array(); $wordCount = count($parts); for ($i = 0; $i < $wordCount; $i++) { $key = $parts[$i]{0}; if (strpos($validKeys, $key) !== false) { $word = substr($parts[$i], 1); } else { $word = $parts[$i]; } $content = iconv(mb_detect_encoding($content, "auto"), 'utf-8', $content); /*if (preg_match("#[ \r\n\t]" . $word . "[ .,\-\r\n\t]#ui", $content)) { var_dump('sss'); }*/ $state[$i] = (boolean) preg_match("#[ \r\n\t]" . $word . "[ .,\-\r\n\t]#ui", $content); if ($key == '-') { $state[$i] = !$state[$i]; } } return array_sum($state) == count($state); Возвращает false, а надо true. ПАУСТОВСКИЙ найдено, а bananana нет.. И в preg_match \b не работает с русскими буквами, поэтому приходится [ .,\-\r\n\t] вот так
Isis Пробуй максимально упрощать данный функции текст (убирать различные пустые строки и ненужные символы), а потом регулярками да и только Помог бы, но с денвером проблема...
В cp1251 \b исполняет правильно PHP: <?php $template = "+ПАУСТОВСКИЙ banananana"; $fileContent = 'Константин Георгиевич ПАУСТОВСКИЙ (1892 1968) Революция, гражданская война, разруха, голод. Константин Паустовский был свидетелем исторических перемен —времени, когда '; $parts = explode(' ', $template); $validKeys = '+-'; $state = $keys = array(); $wordCount = count($parts); for ($i = 0; $i < $wordCount; $i++) { $key = $parts[$i]{0}; $keys[$i] = $key; if (strpos($validKeys, $key) !== false) { $word = substr($parts[$i], 1); } else { $word = $parts[$i]; } $state[$i] = (boolean) preg_match("/\b{$word}\b/i", $fileContent); if ($key == '-') { $state[$i] = !$state[$i]; } } //var_dump($state); $result = true; for ($i = 0; $i < count($state); $i++) { if (strpos($validKeys, $key) !== false) { $result = $result && $state[$i]; } } var_dump($result);
Fuckel, блин блинский)) Если задать шаблон из фраз которых нету вообще в файле, то он возвращает true ... Пробовал менять изначальный result на false - работает, но когда опять сделать темплейт как в прошлом примере, то не пашет.. Логика такая логика, как быть? =)
нашел достаточно ошибок в своем коде: PHP: <?php $template = "+ПАУСТОВСКИЙ banananana"; $fileContent = 'Константин Георгиевич ПАУСТОВСКИЙ (1892 1968) Революция, гражданская война, разруха, голод. Константин Паустовский был свидетелем исторических перемен —времени, когда '; $parts = explode(' ', $template); $validKeys = '+-'; $result = null; $optResult = false; $wordCount = count($parts); for ($i = 0; $i < $wordCount; $i++) { $key = $parts[$i]{0}; if (@strpos($validKeys, $key) !== false) { $word = substr($parts[$i], 1); } else { $word = $parts[$i]; } $state = (boolean) preg_match("/[ \r\n\t]{$word}[ .,\-\r\n\t]/i", $fileContent); if ($key == '-') { $state = !$state; } if (@strpos($validKeys, $key) !== false) { $result = ($result === null) ? $state : $result && $state; } else { $optResult = $optResult || $state; } } $result = $result === null ? $optResult : $result; echo ('Результат: ' . ($result ? 'найдено' : 'не найдено'));
Тут я просто не так объяснил )) На самом деле тут самому не понятно.. если не нашли первое, то второе зачем указывать, хрен поймешь..