парни у меня есть текстовый файл и я хочу удалить некоторые строки, которые содержат определенные слова
<?php
// set source file name and path
$source = "problem.txt";
// read raw text as array
$raw = file($source) or die("Cannot read file");
теперь существует массив, от которого я хочу удалить некоторые строки и хотеть использовать их и так далее.
Поскольку каждая строка вашего файла находится в строке массива, функция array_filter
может вас заинтересовать (цитата) :
array array_filter ( array $input [, callback $callback ] )
Обходит каждое значение во входных данных массив, передающий их функции обратного вызова .
Если функция обратного вызова возвращает истину, текущее значение из input возвращается в массив результатов . Ключи массива сохраняются.
И вы можете использовать strpos
или stripos
, чтобы определить, содержится ли строка в другой строке.
Например, предположим, что у нас есть этот массив:
$arr = array(
'this is a test',
'glop test',
'i like php',
'a badword, glop is',
);
Мы могли бы определить функцию обратного вызова, которая будет отфильтровывать строки, содержащие « glop
»:
function keep_no_glop($line) {
if (strpos($line, 'glop') !== false) {
return false;
}
return true;
}
И использовать эту функцию с array_filter
:
$arr_filtered = array_filter($arr, 'keep_no_glop');
var_dump($arr_filtered);
И мы получим такой вывод:
array
0 => string 'this is a test' (length=14)
2 => string 'i like php' (length=10)
т.е. мы удалили все строки, содержащие «плохое слово» «glop».
Конечно, теперь, когда у вас есть основная идея, ничто не мешает вам использовать более сложную функцию обратного вызова; -)
Редактировать после комментариев: вот полный фрагмент кода, который должен работать:
Прежде всего, у вас есть список строк:
$arr = array(
'this is a test',
'glop test',
'i like php',
'a badword, glop is',
);
Затем вы загружаете список плохих слов из файла:
И вы обрезаете каждую строку и удаляете пустые строки, чтобы убедиться, что вы только "слова" в массиве $ bad_words
, а не пустые данные, которые могут вызвать проблемы.
$bad_words = array_filter(array_map('trim', file('your_file_with_bad_words.txt')));
var_dump($bad_words);
Массив $ bad_words
содержит, из моего тестового файла:
array
0 => string 'glop' (length=4)
1 => string 'test' (length=4)
Затем функция обратного вызова, которая перебирает этот массив плохих слов:
Примечание: использование глобальной переменной не означает хорошо :-( Но функция обратного вызова, вызываемая array_filter
, не получает никаких других параметров, и я не хотел загружать файл каждый раз, когда вызывается функция обратного вызова.
function keep_no_glop($line) {
global $bad_words;
foreach ($bad_words as $bad_word) {
if (strpos($line, $bad_word) !== false) {
return false;
}
}
return true;
}
И, как и раньше , вы можете использовать array_filter
для фильтрации строк:
$arr_filtered = array_filter($arr, 'keep_no_glop');
var_dump($arr_filtered);
Что на этот раз дает вам:
array
2 => string 'i like php' (length=10)
<?php
$source = "problem.txt";
$raw = file_get_contents($source) or die("Cannot read file");
$wordlist = "martin|methew|asshole";
$raw = preg_replace("/($wordlist)/ie", "", $raw);
file_put_contents($source, $raw);
?>
Проверьте функцию strpos . Он может сказать вам, содержит ли строка другую строку или нет (и где именно первая строка находится во второй). Вы можете использовать его так:
$good = array();
$bad_words = array('martin', 'methew');
// for every line in the file
foreach($raw as $line) {
// check for each word we want to avoid
foreach($bad_words as $word) {
// if this line has a trigger word
if(strpos($line, $word) !== false) {
// skip it and start processing the next
continue 2;
}
}
// no triggers hit, line is clean
$good[] = $line;
}
Теперь у вас будет список только чистых строк в $ good
.
Это удалит все строки, в которых есть слово из черного списка:
$rows = file("problem.txt");
$blacklist = "foo|bar|lol";
foreach($rows as $key => $row) {
if(preg_match("/($blacklist)/", $row)) {
unset($rows[$key]);
}
}
file_put_contents("solved.txt", implode("\n", $rows));
Или, если вы используете PHP 5.3, вы можете использовать лямбда-функцию с array_filter:
$rows = file("problem.txt");
$blacklist = "foo|bar|lol";
$rows = array_filter($rows, function($row) {
return preg_match("/($blacklist)/", $row);
});
file_put_contents("solved.txt", implode("\n", $rows));
До PHP 5.3 решение с использованием array_filter
фактически использовало бы больше строк, чем первое решение, которое я опубликовал, поэтому я опускаю это.
Предположим, у вас есть массив «плохих слов»:
<?php
foreach ($raw as $key=>$line)
{
foreach ($badwords as $w)
{
if ( strpos($line, $w) !== false )
unset($raw[$key]);
}
}
?>
$file=file("problem.txt");
$a = preg_grep("/martin|john/",$file,PREG_GREP_INVERT );
print_r($a);