PHP: Как заменить некоторый текст из n-й строки в m-ю строку из файла?

У меня есть файл как some.txt имеющий содержание:

#start-first
Line 1
Line 2
Line 3
#end-first

#start-second
Line 1
Line 2
Line 3
Line 4
#end-second

#start-n
Line 1
Line 2
Line 3
Line 4
...
...
#end-n

Я хочу удалить контент из файла из #start-second в #end-second или из #start-n в #end-n, на самом деле #start-second является Начать маркер за Второй текстовый блок файла и #end-second является Маркер конца за Второй текстовый блок файла.

Как удалить содержимое из конкретного начального блока в тот же конечный блок?

0

Решение

Если эти файлы действительно большие, есть довольно легкое решение:

$file = file_get_contents("example.txt");
// Find the start "#start-$block", "#end-$block" and the length between them:
$start = strpos($file, "#start-$block");
$end = strpos($file, "#end-$block");
$length = $end-$start+strlen("#end-$block");

$file = substr_replace($file, '', $start, length);
file_put_contents("example.txt", $file);

Мой оригинальный ответ начался с регулярного выражения:

$block = 4;

// Open the file
$file = openfile("example.txt");

// replace #start-$block, #end-$block, and everything inbetween with ''
$file = preg_replace("/#start\-".$block."(?:.*?)#end\-".$block."/s", '', $file);

// Save the changes
file_put_contents("example.txt", $file);

Регулярные выражения хотя и дороги, но иногда их легче понять.

2

Другие решения

Вот мое решение:

Это немного сложнее сделать построчно, но это позволяет вам лучше управлять памятью для больших файлов, потому что вы не открываете весь файл сразу. Также вы можете заменить несколько блоков таким образом.

$file = 'test.txt';
//open file to read from
$f = fopen(__DIR__.DIRECTORY_SEPARATOR.$file,'r');
//open file to write to
$w = fopen(__DIR__.DIRECTORY_SEPARATOR.'out-'.$file,'w');

$state = 'start';  //start, middle, end

//start - write while looking for a start tag ( set to middle )
//middle - skip while looking for end tag  ( set to end )
//end - skip while empty ( set to start when not )

//Tags
$start = ['#start-second'];
$end = ['#end-second'];

//read each line from the file
while( $line = fgets($f)){
if( $state == 'end' && !empty(trim($line))){
//set to start on first non empty line after tag
$state = 'start';
}

if( $state == 'start' ){
if(in_array(trim($line),$start)){
$state = 'middle';
}else{
fwrite($w, $line);
}
}else if( $state == 'middle' ){
if(in_array(trim($line),$end)){
$state = 'end';
}
}
}
//close both files
fclose($f);
fclose($w);

//delete the input file
//unlink(__DIR__.DIRECTORY_SEPARATOR.$file);

//for debugging only
echo "<pre>";
echo file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'out-'.$file)

И выход

#start-first
Line 1
Line 2
Line 3
#end-first

#start-n
Line 1
Line 2
Line 3
Line 4
...
...
#end-n

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

Большинство песочниц PHP (или песочниц в целом) не позволяют использовать функции по соображениям безопасности. Тем не менее, мы можем emulate тело кода, синтаксический анализ, в некоторой степени. Вот что я сделал здесь.

http://sandbox.onlinephpfunctions.com/code/0a746fb79041d30fcbddd5bcb00237fcdd8eea2f

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

   /**
* @var string  $pathName - full path to input file
* @var string  $outputName - name of output file
* @var array $tags - array of tags ex. ['start'=>['tag1'],'end'=>[...]]
* @return string - path to output file
*/
function($pathName, $outputName, array $tags){
....
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector