Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [PHP] Скрипт фильтрации по словам


Автор: viperson 14.4.2009, 18:09
Здравствуйте!

Нужен скрипт кторый позволит фильтровать тест по конкретным словам.

Есть текстовый файл в котором находятся русские фразы по одной на строку input.txt,

Есть текстовый файл с русскими словами фильтрами filter.txt,

Необходимо чтобы скрипт удалил все фразы в input.txt содержащих слова в filter.txt

Если есть возможность, необходимо чтобы фильтрация не зависила от языка(рус, англ и тд)

Буду очень признателен.  smile 





Автор: enof 14.4.2009, 18:26
Код

$filter = explode(" ", file_get_contents("filter.txt"));
$pattern = "#^.*(?:".implode("|", $filter).").*$#mu";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

Автор: viperson 14.4.2009, 18:58
Цитата(enof @ 14.4.2009,  18:26)
Код

<?
$filter = explode(" ", file_get_contents("filter.txt"));
$pattern = "#^.*(?:".implode("|", $filter).").*$#mu";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.
?>

выдает ошибку

Compilation failed: invalid UTF-8 string at offset 24 in Z:\home\localhost\www\rusfilter\index.php on line 5

Автор: enof 14.4.2009, 19:01
Модификатор u уберите.

Автор: viperson 14.4.2009, 19:03
я не знаю как это сделать так как не знаю что это такое

Автор: enof 14.4.2009, 19:05
Тогда может быть вам надо в центр помощи?
Выведите на экран получившийся шаблон и скиньте.
Код

echo $pattern;


Добавлено через 59 секунд
И еще, подразумевается, что слова в filter.txt разделены пробелом.

Автор: viperson 14.4.2009, 19:12
Слова в filter.txt одиночные, то есть не разделены пробелом.

Warning: preg_replace() [function.preg-replace]: Compilation failed: invalid UTF-8 string at offset 24 in Z:\home\localhost\www\rusfilter\index.php on line 5
#^.*(?:url guest asp интернет магазин смс sms доска comment blog blogs phpbb send bbs message journal yabb клуб ipb товар topic регистрац регестрац безплатно бисплатно rapidshare files letitbit vipfiles www сайт site forum форум http : . + - / \ _ send thread чат рассказ расказ coment тема бесплатн купит что где игр комикс русск таганрог москв питер петер беларус россия самара омск челябинск киев уфа символик красноярск шоп дети зоо zoo саранск животн posting post владивосток новосибирск атрибут создать сообщение wap набережные челны перм новгород заказ телефон мебел истор обои отель ростов знакомств краснодар студи техник термин клан 3d сценари сесси ру com анекдот замок каталог стать тюмен стиль украина тула открыт казань гипс парсинг берлин аватар tube ссылк воронеж услуг стервятник вечеринк пылесос харьков школа пони тольят литератур отчет расшифровк свитч девайс волгоград снег рисован нижний тагил генеколог электр манг встреч практик читат юмор гипс берлин крым free станк досуг минск пони торрент torrent торент torent екатеринбург белгород промыван желуд для флэш flash ).*$#mu

Автор: enof 14.4.2009, 19:13
viperson, Какие еще одиночные? Чем разделены друг от друга?

Автор: viperson 14.4.2009, 19:15
одно слово на строку, поэтому без пробелов. Я расположил слова через пробел, тоже нет ни какого результата.

Я

Автор: enof 14.4.2009, 19:32
Код

$pattern = "#^.*(?:";
$f = fopen("filter.txt", "r");
$i = 0;
while(!feof($f))
{
    $a = preg_replace("#\r?\n#", "",preg_quote(fgets($f)));
    if($i++ == 0) $pattern .= "$a"; else $pattern .= "|$a";
}
$pattern .= ").*$#mx";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

вот.

Если по слову на каждой строке, то значит слова разделены символом переноса строки. Так сложно сказать?
И в чем проявляется не работа скрипта?

Автор: viperson 14.4.2009, 19:38
Цитата(enof @ 14.4.2009,  19:32)
Код

$pattern = "#^.*(?:";
$f = fopen("filter.txt", "r");
$i = 0;
while(!feof($f))
{
    $a = preg_replace("#\r?\n#", "",preg_quote(fgets($f)));
    if($i++ == 0) $pattern .= "$a"; else $pattern .= "|$a";
}
$pattern .= ").*$#mx";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

вот.

Если по слову на каждой строке, то значит слова разделены символом переноса строки. Так сложно сказать?
И в чем проявляется не работа скрипта?

ошибок не выдает, но и фильтрации не происходит

Автор: enof 14.4.2009, 19:40
Всмысле не происходит? Вы в файл пишите, или выводите куда потом?

Автор: viperson 14.4.2009, 19:43
та никуда я не пишу. Я не понимаю в пхп. Дайте код, например чтобы писало в out.txt плиз 

Автор: skyboy 14.4.2009, 19:47
Для домашних заданий, курсовых, существует "Центр Помощи".

Тема перенесена! 

Автор: enof 14.4.2009, 19:48
viperson,  ###.  smile  Комментарий прочитайте на последней строке.
http://php.net/file_put_contents

Автор: viperson 14.4.2009, 20:06
Что так трудно дописать в скрипт пару строк? Я же говорю что не понимаю в пхп и прошу дописать то что надо, чтобы результат сложило в out.txt

Автор: bars80080 14.4.2009, 22:16
что, так трудно прочитать пару строк? или все здесь неимоверным усилием воли сами в себе генерируют документацию?
тогда да, это недоступная простым смертным магия

Автор: viperson 14.4.2009, 22:48
Цитата(bars80080 @ 14.4.2009,  22:16)
что, так трудно прочитать пару строк? или все здесь неимоверным усилием воли сами в себе генерируют документацию?
тогда да, это недоступная простым смертным магия

что, так трудно написать пару строк? я же сказал не понимаю я в пхп. Подруга попросила помочь, моей целью не является изучать пхп, а просто прошу помочь в решении вопроса. Почему все такие умные?! Помогли бы и дело с концом. Прошу ведь не денег в займы.

Автор: MoLeX 15.4.2009, 05:45
Цитата(viperson @  14.4.2009,  22:48 Найти цитируемый пост)
что, так трудно написать пару строк?

тебе их и так написали!


Цитата(viperson @  14.4.2009,  22:48 Найти цитируемый пост)
Подруга попросила помочь, моей целью не является изучать пхп, а просто прошу помочь в решении вопроса.

Сам не разбираешься в вопросе, а еще берешься разобраться и помочь человеку! И всю работу перелаживаешь со своих плеч, на плечи незнакомым тебе людей при чем умудряешься им же и хамить.

Автор: viperson 15.4.2009, 07:38
Цитата(MoLeX @  15.4.2009,  05:45 Найти цитируемый пост)
Сам не разбираешься в вопросе, а еще берешься разобраться и помочь человеку! И всю работу перелаживаешь со своих плеч, на плечи незнакомым тебе людей при чем умудряешься им же и хамить.



Ну а как бы ты поступил? Отказал бы в помощи? И я никому не хомил. Все то время, что мы тут общаемся всем знактокам пхп не составило бы труда написать пару строк для завершения скрипта, но нет же надо поиздеваться, хотя я сразу написал что я не знаток и прошу помощи.

Автор: MoLeX 15.4.2009, 07:48
Цитата(viperson @  15.4.2009,  07:38 Найти цитируемый пост)
Отказал бы в помощи?

конечно, если я не в теме то сорри. или же попытался вникнуть в тему

Автор: viperson 15.4.2009, 08:21
Так все таки кто-то поможет домучать скрипт? Необходимо чтобы результат записывался в out.txt

Код

$pattern = "#^.*(?:";
$f = fopen("filter.txt", "r");
$i = 0;
while(!feof($f))
{
    $a = preg_replace("#\r?\n#", "",preg_quote(fgets($f)));
    if($i++ == 0) $pattern .= "$a"; else $pattern .= "|$a";
}
$pattern .= ").*$#mx";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.


Автор: MoLeX 15.4.2009, 08:26
http://ru.php.net/manual/ru/function.fwrite.php

Автор: viperson 15.4.2009, 09:03
Мне понятен код

Код

$filename = 'test.txt';
$somecontent = "Добавить это к файлу\n";

// Вначале давайте убедимся, что файл существует и доступен для записи.
if (is_writable($filename)) {

    // В нашем примере мы открываем $filename в режиме "дописать в конец".
    // Таким образом, смещение установлено в конец файла и
    // наш $somecontent допишется в конец при использовании fwrite().
    if (!$handle = fopen($filename, 'a')) {
         echo "Не могу открыть файл ($filename)";
         exit;
    }

    // Записываем $somecontent в наш открытый файл.
    if (fwrite($handle, $somecontent) === FALSE) {
        echo "Не могу произвести запись в файл ($filename)";
        exit;
    }
    
    echo "Ура! Записали ($somecontent) в файл ($filename)";
    
    fclose($handle);

} else {
    echo "Файл $filename недоступен для записи";
}


но как мне увязать его с моим кодом?

Автор: MoLeX 15.4.2009, 09:06
как я понял в переменной $subj у тебя то что тебе надо сохранить?
Код

$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.


вот бери эту переменную и сохраняй

Автор: viperson 15.4.2009, 10:05
что-то не так со скриптом. Сохраняет пустой файл.
Код

<?
$pattern = "#^.*(?:";
$f = fopen("filter.txt", "r");
$i = 0;
while(!feof($f))
{
    $a = preg_replace("#\r?\n#", "",preg_quote(fgets($f)));
    if($i++ == 0) $pattern .= "$a"; else $pattern .= "|$a";
}
$pattern .= ").*$#m";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

// начало записи в файл

$filename = 'out.txt';
$somecontent = "$subj\n";

// Вначале давайте убедимся, что файл существует и доступен для записи.
if (is_writable($filename)) {

    // В нашем примере мы открываем $filename в режиме "дописать в конец".
    // Таким образом, смещение установлено в конец файла и
    // наш $somecontent допишется в конец при использовании fwrite().
    if (!$handle = fopen($filename, 'a')) {
         echo "Не могу открыть файл ($filename)";
         exit;
    }

    // Записываем $somecontent в наш открытый файл.
    if (fwrite($handle, $somecontent) === FALSE) {
        echo "Не могу произвести запись в файл ($filename)";
        exit;
    }
    
    echo "Ура! Записали ($somecontent) в файл ($filename)";
    
    fclose($handle);

} else {
    echo "Файл $filename недоступен для записи";
}


?>


не могу понять что не так. Отработка скрипта происходит без ошибок.

Я так понимаю что может скрипт не понимает что такое "электр". Имеется ввиду и электон и элетонный  и электрический. То есть надо как-то показать скрипту, что необходимо удалить все строки содержащие этот кусок слова. 

Может причина в другом, пока мне понятно.

Автор: bars80080 15.4.2009, 10:05
Код

$pattern = "#^.*(?:";
$f = fopen("filter.txt", "r");
$i = 0;
while(!feof($f))
{
    $a = preg_replace("#\r?\n#", "",preg_quote(fgets($f)));
    if($i++ == 0) $pattern .= "$a"; else $pattern .= "|$a";
}
$pattern .= ").*$#mx";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

// единственное, что забыл автор - закрыть файл
fclose($f);


// а здесь добавляем второй пример
$filename = 'input.txt';
$somecontent = $subj;

// Вначале давайте убедимся, что файл существует и доступен для записи.
if (is_writable($filename)) {

    // В нашем примере мы открываем $filename в режиме "дописать в конец".
    // Таким образом, смещение установлено в конец файла и
    // наш $somecontent допишется в конец при использовании fwrite().
    if (!$handle = fopen($filename, 'a')) {
         echo "Не могу открыть файл ($filename)";
         exit;
    }

    // Записываем $somecontent в наш открытый файл.
    if (fwrite($handle, $somecontent) === FALSE) {
        echo "Не могу произвести запись в файл ($filename)";
        exit;
    }
    
    echo "Ура! Записали ($somecontent) в файл ($filename)";
    
    fclose($handle);

} else {
    echo "Файл $filename недоступен для записи";
}

и что, много изменений?

если нужно не дописать в конец файла, а полностью перезаписать, то вместо 'a' надо поставить 'w' в строчке 
if (!$handle = fopen($filename, 'a')) { 
, что написано в описании к http://ru.php.net/manual/ru/function.fopen.php по-русски

Автор: viperson 15.4.2009, 10:21
Цитата(bars80080 @  15.4.2009,  10:05 Найти цитируемый пост)
и что, много изменений?

если нужно не дописать в конец файла, а полностью перезаписать, то вместо 'a' надо поставить 'w' в строчке 
if (!$handle = fopen($filename, 'a')) { 
, что написано в описании к fopen по-русски


Да не много, но по прежнему файл записывается пустой. То есть записыввается, но пустые строки.


я заменил

Код

// а здесь добавляем второй пример
$filename = 'input.txt';


на 

Код

// а здесь добавляем второй пример
$filename = 'out.txt';


для записи результата в отдельный файл.

Может быть для Denwer 3 не подходит такая реализация?

Автор: bars80080 15.4.2009, 13:58
не, проверь вначале, что у тебя в $subj:

Код

$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.

var_dump($subj);

// начало записи в файл


что напишет, скопируй сюда

Добавлено через 32 секунды
напишет - в смысле, выдаст в браузер

Автор: viperson 15.4.2009, 14:02
Цитата(bars80080 @  15.4.2009,  13:58 Найти цитируемый пост)
что напишет, скопируй сюда

Добавлено через 32 секунды
напишет - в смысле, выдаст в браузер



string(1768) " " Ура! Записали ( ) в файл (out.txt)


количество записей в файле input.txt = 1769, в файле out.txt такое же количество пустых строк


почему-то указывает на на предыдущую строку

Автор: enof 15.4.2009, 14:27
Скинь примеры файлов.

Автор: bars80080 15.4.2009, 15:46
это результат работы всех этих preg_replace, 
тут два варианта, либо твои фильтры так хороши, что вообще всё вычищают,
либо автор кривовато написал (впрочем, если у него не было оригинальных файлов, то вполне можно было ожидать)

если понимаешь, что в регулярках /регулярные выражения - это не пхп/ (я лично нет), то можешь сам попытаться исправить, 
если нет, то придётся возвращаться в раздел пхп и делать тему: мол такой вот код, с такими файлами не корректно работает, отдаёт пустые строки

Добавлено через 1 минуту и 9 секунд
а может и здесь объяснят

Автор: enof 15.4.2009, 16:38
input.txt
Код

Здравствуйте!
Нужен скрипт кторый позволит фильтровать тест по конкретным словам.
Есть текстовый файл в котором находятся русские фразы по одной на строку input.txt,
Есть текстовый файл с русскими словами фильтрами filter.txt,
Необходимо чтобы скрипт удалил все фразы в input.txt содержащих слова в filter.txt
Если есть возможность, необходимо чтобы фильтрация не зависила от языка(рус, англ и тд)

filter.txt
Код

текс
файл
!
англ

index.php
Код

<?php
$pattern = "#^.*(?:";
$filter = file_get_contents("filter.txt");
$arr_filter = explode("\n", $filter);   //Если винда, заменить \n на \r\n
array_pop($arr_filter);
foreach($arr_filter as &$v)
    $v = preg_quote($v, "#");
$pattern .= implode("|", $arr_filter). ").*$#m";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.
$subj = preg_replace("#(^|\r?\n)\r?\n#", "", $subj);
file_put_contents("out.txt", $subj);
?>

Получаем out.txt
Код

Нужен скрипт кторый позволит фильтровать тест по конкретным словам.
Необходимо чтобы скрипт удалил все фразы в input.txt содержащих слова в filter.txt

Все проверил, все работает.

Автор: viperson 15.4.2009, 17:11
Цитата(enof @  15.4.2009,  16:38 Найти цитируемый пост)
<?php
$pattern = "#^.*(?:";
$filter = file_get_contents("filter.txt");
$arr_filter = explode("\n", $filter);   //Если винда, заменить \n на \r\n
array_pop($arr_filter);
foreach($arr_filter as &$v)
    $v = preg_quote($v, "#");
$pattern .= implode("|", $arr_filter). ").*$#m";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.
$subj = preg_replace("#(^|\r?\n)\r?\n#", "", $subj);
file_put_contents("out.txt", $subj);
?>


Походу пашет. Но будет ли он правильно фильтровать, если в фильтре слово "элек" подразумевает удаление слов электронный и электрический и тд?

Автор: enof 15.4.2009, 17:15
smile  Скрипту насрать на ваши слова. Он ищет последовательность символов в строке, если встречается, то удаляет.

Добавлено через 25 секунд
Это так сложно проверить?

Автор: viperson 15.4.2009, 17:18
Цитата(enof @  15.4.2009,  16:38 Найти цитируемый пост)
<?php
$pattern = "#^.*(?:";
$filter = file_get_contents("filter.txt");
$arr_filter = explode("\n", $filter);   //Если винда, заменить \n на \r\n
array_pop($arr_filter);
foreach($arr_filter as &$v)
    $v = preg_quote($v, "#");
$pattern .= implode("|", $arr_filter). ").*$#m";
$subj = file_get_contents("input.txt");
$subj = preg_replace($pattern, "", $subj); // В $subj очищенный текст.
$subj = preg_replace("#(^|\r?\n)\r?\n#", "", $subj);
file_put_contents("out.txt", $subj);
?>


Походу пашет. Но будет ли он правильно фильтровать, если в фильтре слово "элек" подразумевает удаление слов электронный и электрический и тд?

Одна только проблемка - если слово-фильтр и слово слитно в тексте, то скрипт не понимает.

Автор: enof 15.4.2009, 17:28
С вами все впорядке?

Автор: viperson 15.4.2009, 17:31
Цитата(enof @  15.4.2009,  17:28 Найти цитируемый пост)
С вами все впорядке? 


Да со мной все OK! Спасибо что поинтересовались.

Одна только проблемка - если слово-фильтр и слово слитно в тексте, то скрипт не понимает, то есть не удаляет эти строки

Автор: enof 15.4.2009, 17:37
Скрипт не понимает предложений, фраз, слов и т.д. Он ищет в строке последовательность символов, если находит, то удаляет строку.
И если вы посмотрите на мой пост, то увидите в фильтре "текс", и также не увидите в out.txt строк, содержащих слов "текстовый".
Поэтому и интересовался.

Автор: viperson 15.4.2009, 18:57
Еще один маленький нюанс - это то, что после удаления строк по фильтрам, он не переносит некоторые строки, то есть

изначально сроки выглядели так:

aaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccc
dddddddddddddddddddd

после удаления  по фильтру bbbbbbbbbbbbbbbbbbbb получается:

aaaaaaaaaaaaaaaaaaaa
cccccccccccccccccccccccccccdddddddddddddddddddd

в конечном файле

ну и фильтрация почему-то не на 100 процентов происходит, то есть присутсвуют не удаленые строки. Может нужна двойная фильтрация?


Автор: enof 15.4.2009, 19:09
Цитата(viperson @  15.4.2009,  19:57 Найти цитируемый пост)
ну и фильтрация почему-то не на 100 процентов происходит, то есть присутсвуют не удаленые строки. Может нужна двойная фильтрация?

ага, она самая. приведите реальные файлы, на которых вы все это делаете.

Добавлено @ 19:11
Цитата(viperson @  15.4.2009,  19:57 Найти цитируемый пост)
Еще один маленький нюанс - это то, что после удаления строк по фильтрам, он не переносит некоторые строки, то есть

уберите 11 строчку.

Добавлено @ 19:14
А не, чет ступил, 
11 строка
Код

$subj = preg_replace("#(^|\r?\n)(\r?\n)+#", "$1", $subj);

Автор: viperson 15.4.2009, 19:33
Цитата(enof @  15.4.2009,  19:09 Найти цитируемый пост)
ага, она самая. приведите реальные файлы, на которых вы все это делаете.


- Фильтрация проходит по всем буквам английской раскладки по некоторым ненужным русским словам и по знакам препинания типа ?/>< 


Автор: enof 15.4.2009, 19:39
Киньте два файла, filter.txt и input.txt, на каких не работает фильтрация.

Автор: viperson 15.4.2009, 21:56
сорри уже все заработало

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)