如何使用PHP替换文本文件中的特定行?

时间:2010-06-09 08:09:43

标签: php

如何使用php替换特定行。我不知道行号。我想替换包含特定单词的行。

10 个答案:

答案 0 :(得分:51)

您可以在可以适合您的内存两次的较小文件上使用的一种方法:

$data = file('myfile'); // reads an array of lines
function replace_a_line($data) {
   if (stristr($data, 'certain word')) {
     return "replaement line!\n";
   }
   return $data;
}
$data = array_map('replace_a_line',$data);
file_put_contents('myfile', implode('', $data));

快速说明,PHP> 5.3.0支持lambda函数,因此您可以删除指定的函数声明并将映射缩短为:

$data = array_map(function($data) {
  return stristr($data,'certain word') ? "replacement line\n" : $data;
}, $data);

理论上你可以将它作为单个(更难遵循)的php语句:

file_put_contents('myfile', implode('', 
  array_map(function($data) {
    return stristr($data,'certain word') ? "replacement line\n" : $data;
  }, file('myfile'))
));

您应该用于较大文件的另一种(内存不足)方法:

$reading = fopen('myfile', 'r');
$writing = fopen('myfile.tmp', 'w');

$replaced = false;

while (!feof($reading)) {
  $line = fgets($reading);
  if (stristr($line,'certain word')) {
    $line = "replacement line!\n";
    $replaced = true;
  }
  fputs($writing, $line);
}
fclose($reading); fclose($writing);
// might as well not overwrite the file if we didn't replace anything
if ($replaced) 
{
  rename('myfile.tmp', 'myfile');
} else {
  unlink('myfile.tmp');
}

答案 1 :(得分:7)

您必须覆盖整个文件。

因此,对于相对较小的文件read file into array,搜索单词,替换找到的行,将all the rest写入file

对于大文件,算法略有不同,但总的来说非常相似。

重要的部分是file locking

这就是我们更喜欢数据库的原因。

答案 2 :(得分:3)

您还可以使用带有正则表达式的多行模式

preg_match_all('/word}/m', $textfile, $matches);
当然,这是假设它在准备好并加载时是一个较小的文档。否则,其他答案更像是“现实世界”的解决方案。

答案 3 :(得分:2)

$filedata = file('filename');
$newdata = array();
$lookfor = 'replaceme';
$newtext = 'withme';

foreach ($filedata as $filerow) {
  if (strstr($filerow, $lookfor) !== false)
    $filerow = $newtext;
  $newdata[] = $filerow;
}

现在$newdata包含文件内容作为数组(如果你不想要数组,请使用implode()),并将包含“replaceme”的行替换为“withme”。

答案 4 :(得分:1)

如果您不知道该行,则必须搜索所有行。

iterate over the file line by lineread the file into memory all at once。 然后,使用strposstr_replace或组合查找单词 使用preg_replace

如果您进行迭代,只需使用strpos并在未返回FALSE时替换该行。然后将文件保存回磁盘。

答案 5 :(得分:1)

如果您要在一行中查找子字符串(ID)并希望用新行替换旧行,这很好。

<强>代码:

$id = "123";
$new_line = "123,Programmer\r"; // We're not changing the ID, so ID 123 remains.
$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $id) !== false) { // if file contains ID
    $contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
    foreach ($contents_array as &$record) {    // for each line
        if (strpos($record, $id) !== false) { // if we have found the correct line
            $new_contents .= $new_line; // change record to new record
        }else{
            $new_contents .= $record . "\r";
        }
    }
    file_put_contents($dir, $new_contents); // save the records to the file
    echo json_encode("Successfully updated record!");
}
else{
    echo json_encode("failed - user ID ". $id ." doesn't exist!");
}

示例:

旧文件:

  

ID,职业

     

123,学生

     

124,砖层

运行代码会将文件更改为:

新文件:

  

ID,职业

     

123,程序员

     

124,砖层

答案 6 :(得分:0)

也许这可能会有所帮助:

$data = file("data.php");

for($i = 0;$i<count($data);$i++){
    echo "<form action='index.php' method='post'>";
    echo "<input type='text' value='$data[$i]' name='id[]'><br>";
}

echo "<input type='submit' value='simpan'>";
echo "</form>";

if(isset($_POST['id'])){
    file_put_contents('data.php',implode("\n",$_POST['id'])) ;
}

答案 7 :(得分:0)

您可以使用explode();函数将文件转换为数组,编辑数组中的任何项目,使用implode();函数将数组转换回字符串,然后您可以将字符串放入使用file_put_contents();函数返回文件。这在以下功能中显示:

function file_edit_contents($file_name, $line, $new_value){
  $file = explode("\n", rtrim(file_get_contents($file_name)));
  $file[$line] = $new_value;
  $file = implode("\n", $file);
  file_put_contents($file_name, $file);
}

答案 8 :(得分:0)

你可以这样做:

$file = file('data.txt'); 
$data = 'new text';
$some_index = 2;
foreach($file as $index => $line){

   if($index == $some_index){
       $file[$index] = $data . "\n";
   }

}

$content = implode($file);
file_put_contents('data.txt', $content);

答案 9 :(得分:0)

这个函数应该替换文件中的整行:

function replace($line, $file) {
    if ( file_get_contents($file) == $line ) {
        file_put_contents($file, '');
    } else if ( file($file)[0] == $line.PHP_EOL ) {
        file_put_contents($file, str_replace($line.PHP_EOL, '', file_get_contents($file)));
    } else {
        file_put_contents($file, str_replace(PHP_EOL.$line, '', file_get_contents($file)));
    }
}

第一个 if 语句(第 2 行)检查要删除的行是否是唯一的行。然后它清空文件。第二个 if 语句(第 4 行)检查要删除的行是否是文件中的第一行。如果是,则继续使用 str_replace($line.PHP_EOL, '', file_get_contents($file)) 删除该行。 PHP_EOL 是一个新行,因此这将删除行内容,然后是换行符。最后,只有当要删除的行不是唯一的内容并且不在文件的开头时,才会调用 else 语句。然后它使用 str_replace,但这次使用 PHP_EOL.$line 而不是 $line.PHP_EOL。这样,如果该行是文件的最后一行,它将删除它之前的换行符,然后删除该行。

用法:

replace("message", "database.txt");

这将从文件 message 中删除内容为 database.txt 的行(如果该行存在)。如果你想缩短它,你可以这样做:

function replace($line,$file){if(file_get_contents($file)==$line){file_put_contents($file,'');}else if(file($file)[0]==$line.PHP_EOL){file_put_contents($file,str_replace($line.PHP_EOL,'', file_get_contents($file)));}else{file_put_contents($file,str_replace(PHP_EOL.$line,'',file_get_contents($file)));}}

我希望能回答你的问题:)