Удалить строку, содержащую определенные слова / фразы с PHP - PullRequest
5 голосов
/ 15 февраля 2010

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

 <?php
// set source file name and path
$source = "problem.txt";

// read raw text as array
$raw = file($source) or die("Cannot read file");

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

Ответы [ 7 ]

7 голосов
/ 15 февраля 2010

Поскольку каждая строка вашего файла находится в строке массива, функция array_filter может вас заинтересовать (цитирование) :

array array_filter  ( array $input  [, callback $callback  ] )

Итерация по каждому значению на входе массив, передавая их обратному вызову функция.
Если обратный вызов функция возвращает true, текущий значение из ввода возвращается в массив результатов. Ключи массива сохраняется.

И вы можете использовать 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)

т.е. мы удалили все строки, содержащие "badword" и "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)
3 голосов
/ 15 февраля 2010
$file=file("problem.txt");
$a = preg_grep("/martin|john/",$file,PREG_GREP_INVERT );
print_r($a);
2 голосов
/ 07 марта 2013

Если у вас длинная строка, а не файл, и вы хотите удалить все строки, содержащие определенные слова. Вы можете использовать это:

$string="I have a long string\n
  That has good words inside.\n
   I love my string.\n
  //add some words here\n";
$rows = explode("\n",$string);
$unwanted = "tring|\/\/";
$cleanArray= preg_grep("/$unwanted/i",$rows,PREG_GREP_INVERT);
$cleanString=implode("\n",$cleanArray);
print_r ( $cleanString );

Это удаляет строки, содержащие "tring" и "//".

2 голосов
/ 15 февраля 2010

Это удалит все строки , в которых есть слово из черного списка:

$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, фактически занимало бы больше строк, чем первое опубликованное мной решение, поэтому я опущу это.

2 голосов
/ 15 февраля 2010

Проверьте функцию 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.

1 голос
/ 15 февраля 2010

Предполагая, что у вас есть массив "плохих слов":

<?php
foreach ($raw as $key=>$line)
{
    foreach ($badwords as $w)
    {
        if ( strpos($line, $w) !== false )
            unset($raw[$key]);
    }
}
?>
0 голосов
/ 15 февраля 2010
<?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);
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...