Strict Standards: Resource ID#18 used as offset, casting to integer (18) in /home/tvoyweb/domains/tvoyweb.ru/public_html/forums/include/fm.class.php on line 401

Strict Standards: Resource ID#23 used as offset, casting to integer (23) in /home/tvoyweb/domains/tvoyweb.ru/public_html/forums/include/fm.class.php on line 401

Strict Standards: Resource ID#25 used as offset, casting to integer (25) in /home/tvoyweb/domains/tvoyweb.ru/public_html/forums/include/fm.class.php on line 401

Strict Standards: Resource ID#26 used as offset, casting to integer (26) in /home/tvoyweb/domains/tvoyweb.ru/public_html/forums/include/fm.class.php on line 401
ТвойWeb :: Поиск по списку на PHP
ТвойWeb ТвойWeb
Качественный Европейский хостинг
Форум для чайников
 Чат на форуме      Помощь      Поиск      Пользователи


 Страниц (1): [1]   

> Описание: Список разбросан по 26 файлам
UFO
Отправлено: 08 Февраля, 2008 - 09:55:21
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




Привет! Улыбка
Возникла такая задача: реализовать поиск по списку, который записан по частям в файлы от a.dat до z.dat (26_латинских_букв.dat). В каждом файле приблизительно 8 тысяч строк. Но во всех файлах разное кол-во. На каждой строчке восьмисимвольная запись. Как организовать поиск части слова этих записей по каждому из списков? Допустим, пользователь вводит слово "yes", нажимает кнопку и скрипт ищет в каждом файле, на каждой строчке запись, которая содержит в себе слово "yes". Если найдено такое, то выводим его на экран. Было бы неплохо, если бы вывод выглядел приблизительно так:
Цитата:
Файл: a.dat
Найдено:
ayes
iyes
zyes
====
Файл: c.dat
Найдено:
ryes
====
и т.д.

Если в определенном файле ничего не найдено, то можно ничего и не выводить.
Итак, вопрос: как же правильнее и проще всего сделать такой поиск?
 
 Top
Furax
Отправлено: 08 Февраля, 2008 - 23:58:00
Post Id



Бледнотик


Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007  
Откуда: Иркутск, Сибирь, СССР

Карма 32




UFO
Я бы сделал через регулярные выражения. Т. е. введённая пользователем строка преобразуется в regexp и потом это выражение ищется по всему файлу. Что-то типа /\b.*yes.*\b/.

Хотя, если сервак под *nixами, можно воспользоваться системной функцией grep, насчёт синтаксиса которой я подсказать не могу. Короче, через командную строку.

Если же речь идёт о том, как получить имена всех нужных файлов - я бы сделал вот так:
CODE:
foreach (glob('files/?.dat') as $file) ...

(Отредактировано автором: 09 Февраля, 2008 - 00:02:08)

 
 Top
UFO
Отправлено: 10 Февраля, 2008 - 14:30:25
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




Furax
Да, как вывести название файла - ясно, но все таки с поиском не все ясно.
Как сделать так, чтобы выражение искалось во всех 26 файлах? 26 раз писать переменную? И еще: можно по-точнее, функцию какого регулярного выражения надо использовать? preg_match_all? Было бы неплохо, если бы были хоть какие-нибудь наброски кода (извиняюсь за дерзость Улыбка ), т.к. я даже не знаю как реализовать наиболее просто.

(Отредактировано автором: 10 Февраля, 2008 - 14:37:40)

 
 Top
Furax
Отправлено: 11 Февраля, 2008 - 01:22:37
Post Id



Бледнотик


Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007  
Откуда: Иркутск, Сибирь, СССР

Карма 32




UFO
В цикле просмотреть файлы и для каждого по очереди сделать поиск и в случае удачи вывести результат. Да, preg_match_all.

Код? Что-то типа этого:
CODE:
foreach (glob('db/?.dat') as $file)
{
$out=array();
if (preg_match_all($pattern, file_get_contents($file), $out)
{
print "$file:<br> " . implode('<br>', $out) . '<br>';
}
}
Где $pattern - это строка шаблона, сформированная на основе поискового запроса.
 
 Top
UFO
Отправлено: 20 Февраля, 2008 - 14:03:56
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




Все никак не могу разобратся, проблема с preg_match_all и с выводом результата поиска. Вопрос относительно 26 файлов решил упростить - проще сделать всю базу в одном файле и по ней искать. Решено - теперь файл один, но проблемы все равно остались.
На данный момент скрипт выглядит так:
CODE:
<center>Поиск<br>
<form action="<?php echo $_SERVER['PHP_SELF']; echo "?p=find"; ?>" method="POST" name="find">
<input type=text value="<? echo $slovo ?>" size="10" maxlength="4" name="slovo">.net<br>
<a href="index.php" onclick="document.find.submit(); return false">Проверить >>></a></form><br><br>
<?php
if (($act<>null) && ($slovo==null))
{
echo "Не был введен поисковый запрос</center>";
}
if (preg_match("#[^A-Za-z\-]#is",$slovo))
{
echo "Поисковый запрос содержит недопустимые символы или введен не правильно. Допустимые символы: <font color=red>a-z</font> (буквы латинского алфавита) и <font color=red>-</font> (дефис).</center>";
} else
if ($slovo<>null) {
if ((strlen($slovo)<2) or (strlen($slovo)>4)) {
echo "Поисковый запрос должен состоять как минимум из двух, и как максимум из четырех символов";
} else {
$out=array();
$fila = file("pages/db/a.dat");
$lina = count($fila);
for ($i = 0 ; $i < $lina; $i++)
{
if (preg_match_all("/\b.* $slovo .*\b/", $lina[$i], $out))
// Тут начинаются проблемы. Вроде как результат в $out...
echo $lina[$i]; // Это штука в принципе ничего не выводит...
echo implode('<br>', $out); // А это результат, но выглядит он как count($fila) строчек с надписью "Array",
echo "<br>"; // разделенных переводом строки...
}
}
};
?>

Вообщем, проблема описана в комметариях к коду.
Еще есть проблема о том, как сообщить юзверю, что поиск ничего не нашел, т.е. куда ставить
CODE:
echo "Поиск не дал результатов</center>";

При этом использовать break; и exit(); нельзя, т.к. дальше есть еще вывод информации.
 
 Top
Furax
Отправлено: 20 Февраля, 2008 - 22:59:47
Post Id



Бледнотик


Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007  
Откуда: Иркутск, Сибирь, СССР

Карма 32




Э-м-м... А вот это зачем? Почему просто не поставить кнопку submit?
CODE:
<a href="index.php" onclick="document.find.submit(); return false">Проверить >>></a>


А что сие значит (я имею в виду регулярное выражение)? Откуда вообще октоторпы?
CODE:
preg_match("#[^A-Za-z\-]#is",$slovo)
Если это тест на допустимость символов, то я бы сделал так:
CODE:
preg_match('/[^A-Za-z\-А-Яа-я]/',$slovo)


Ещё вопрос: зачем разбиение по строкам при чтении файла, если мы потом ищем всё равно в каждой строке? В каждой строке-то можно и без регулярных выражений искать... Лучше искать сразу везде! Исключение составляют случаи, когда база настолько большая, что не входит в выделяемый скрипту объём оперативной памяти.

Регулярное выражение в preg_match_all составлено неправильно: оно ищет следующую последовательность (записывай): границу слова; любое количество любых символов; пробел; введённое пользователем слово; пробел; любое количество любых символов; границу слова. Кроме того, поскольку строка заключена в двойные кавычки, слэши надо дублировать.

Исправленный мною код выглядит вот так:
CODE:
$fila = file_get_contents("pages/db/a.dat");
if (preg_match_all("/\\b(\\S*$slovo\\S*)\\b/i", $fila, $out, PREG_PATTERN_ORDER))
{
echo implode('<br>', $out[1]);
}
else
{
echo 'Ничего не найдено';
}
Здесь поиск идёт сразу во всём файле, согласованные строки лежат в массиве $out[1]. Кроме того, я добавил ключ i к регулярному выражению, дабы поиск шёл независимо от регистра.
 
 Top
UFO
Отправлено: 21 Февраля, 2008 - 15:03:52
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




Большое спасибо, Furax! Реально помог написать скрипт Улыбка
Цитата:
Э-м-м... А вот это зачем? Почему просто не поставить кнопку submit?

Ссылкой красивее - работает так же как кнопка, но выглядит ссылкой, это чисто понты, дизайн, я и сам понимаю, что так проблем больше, но концепция сайта требует ссылку, а не привычную кнопку.
Цитата:
А что сие значит (я имею в виду регулярное выражение)? Откуда вообще октоторпы?

Просто проверка на введенные символы, чтобы не было запрещенных символов. Скопировал откуда-то давно еще, поэтому и пользуюсь везде этим вариантом. Всегда работало правильно.
Цитата:
Ещё вопрос: зачем разбиение по строкам при чтении файла, если мы потом ищем всё равно в каждой строке? В каждой строке-то можно и без регулярных выражений искать... Лучше искать сразу везде! Исключение составляют случаи, когда база настолько большая, что не входит в выделяемый скрипту объём оперативной памяти.

Я просто хотел создать цикл от i до кол-ва строк в файле, чтобы сравнивать каждую строку в файле с введенным словом в поле, если совпадает - выводим строку из файла на экран. Думал, что алгоритм такой.
Цитата:
Регулярное выражение в preg_match_all составлено неправильно

Ага, в этом была большая проблема - написать граммотно функцию.

Вообщем, еще раз спасибо, все работает как надо Улыбка Подмигивание
Респект Закатив глазки
 
 Top
UFO
Отправлено: 22 Февраля, 2008 - 15:19:36
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




В процессе работы скрипта возник следующий вопрос: можно ли как-либо сделать, чтобы если введенный запрос содержит знак "*", то в поиске этот символ заменяется на последовательность от a до z? Например, поисковый запрос **b* - поиск ищет в списке все слова, имеющие вид символ_символ_b_символ. Может быть это есть в функции preg_math_all? Конечно, можно "*" заменить буквами в цикле и вставить в переменную, но это сложнее, чем готовое решение в виде функции PHP...
 
 Top
Furax
Отправлено: 23 Февраля, 2008 - 00:01:57
Post Id



Бледнотик


Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007  
Откуда: Иркутск, Сибирь, СССР

Карма 32




Перед моим кодом:
CODE:
$slovo = str_replace('*', '\w', $slovo);
Соответственно, регулярное выражение для проверки правильности ввода (которую нужно делать ещё до этой замены) перепишется так:
CODE:
'/[^A-Za-z\-А-Яа-я\*]/'
 
 Top
UFO
Отправлено: 23 Февраля, 2008 - 11:07:29
Post Id



Full Member


Покинул форум
Сообщений всего: 212
Дата рег-ции: Янв. 2005  

Карма 0




Furax, большое спасибо тебе Улыбка
Не думал, что так просто поиск можно модернизировать Улыбка
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 2 (гостей: 2, зарегистрированных: 0, скрытых: 0)
« PHP/Perl »


Все гости форума могут просматривать этот раздел.
Только администраторы и модераторы могут создавать новые темы в этом разделе.
Только администраторы и модераторы могут отвечать на сообщения в этом разделе.
 



Форум на AlfaSpace.NET


Powered by ExBB
ExBB FM 1.0 RC1 by TvoyWeb.ru
InvisionExBB Style converted by Markus®

[Script Execution time: 0.0515]     [ Gzipped ]



Notice: ob_end_flush(): failed to send buffer of ob_gzhandler (1) in /home/tvoyweb/domains/tvoyweb.ru/public_html/forums/include/page_tail.php on line 33