簡體   English   中英

替換在文本文件中找到特定單詞的整行

[英]Replace a whole line where a particular word is found in a text file

如何使用 php 替換文件中的特定文本行?

我不知道行號。 我想替換包含特定單詞的行。

您可以在可以兩次放入內存的較小文件上使用的一種方法:

$data = file('myfile'); // reads an array of lines
function replace_a_line($data) {
   if (stristr($data, 'certain word')) {
     return "replacement line!\n";
   }
   return $data;
}
$data = array_map('replace_a_line', $data);
file_put_contents('myfile', $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');
}

您必須覆蓋整個文件。

因此,對於相對較小的文件,將 file 讀入 array ,搜索單詞,替換找到的行,將其余所有寫入file

對於大文件,算法略有不同,但大致相同。

重要的部分是文件鎖定

這就是為什么我們更喜歡數據庫。

如果您不知道該行,則必須搜索所有行。

逐行遍歷文件一次將文件全部讀入內存 然后要么使用strposstr_replace的組合查找單詞,要么使用preg_replace

如果您進行迭代,只需使用strpos並在它不返回 FALSE 時替換該行。 然后將文件保存回磁盤。

您還可以將多行模式與正則表達式一起使用

preg_match_all('/word}/m', $textfile, $matches);

當然,這是假設它是准備好並已加載的較小文檔。 否則,其他答案是更“現實世界”的解決方案。

$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”。

如果您正在尋找一行中的子字符串 (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!");
}

例子:

舊文件:

身份證、職業

123,學生

124、磚層

運行代碼會將文件更改為:

新文件:

身份證、職業

123,程序員

124、磚層

您可以使用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);
}

也許這會有所幫助:

$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'])) ;
}

此函數應替換文件中的整行:

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");

如果該行存在,這將從文件database.txt中刪除包含內容message的行。 如果你想縮短它,你可以這樣做:

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)));}}

我希望能回答你的問題:)

如果您在處理文件時不打算鎖定文件,那么

  1. 訪問文件,
  2. 修改該行(如果找到)並停止尋找要替換的其他行,
  3. 並以最大速度重新保存它(如果找到)。

也就是說,為了速度而犧牲准確性是沒有意義的。 這個問題指出必須在該行中匹配一個單詞。 因此,必須防止部分匹配——正則表達式提供單詞邊界( \b )。

$filename = 'test.txt';
$needle = 'word';

$newText = preg_replace(
    '/^.*\b' . $needle . '\b.*/mui',
    'whole new line',
    file_get_contents($filename)
    1,
    $count
);
if ($count) {
    file_put_contents($filename, $newText);
}

圖案:

/     #starting pattern delimiter
^     #match start of a line (see m flag)
.*    #match zero or more of any non-newline character
\b    #match zero-width position separating word character and non-word character
word  #match literal string "word"
\b    #match zero-width position separating word character and non-word character
.*    #match zero or more of any non-newline character to end of line
/     #ending pattern delimiter
m     #flag tells ^ character to match the start of any line in the text
u     #flag tells regex engine to read text in multibyte modr
i     #flag tells regex engine to match letters insensitively

如果使用不區分大小寫的搜索,但您需要替換字符串中實際匹配的單詞,請在模式中的針周圍寫括號,然后在替換字符串中使用$1

你可以這樣做:

$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);

我有過類似的任務, gnarf's回答很有幫助。

但更好的方法是 JSON。 如果您必須更改 JSON 文件,您可以使用此代碼。

代碼只是獲取現有的 JSON 並將其應用於變量:

$base_data = json_decode(file_get_contents('data.json'), true);

$ret_data = json_encode($base_data , JSON_PRETTY_PRINT);

根據需要添加/修改$ret_data數組並將其放回文件中:

file_put_contents('data.json', $ret_data)

`

$base_data = json_decode(file_get_contents('data.json'), true);
if(!empty($_POST["update_data_file"])){

    if(empty($_POST["update_key"]) || empty($_POST['update_value'])){

        return_response(false, true, "Update Key or Update Value is missing");
    }

    if(!is_array($_POST["update_key"])){

        return_response(false, false, "Update Key is not an array");

    }

    if(!is_array($_POST["update_value"])){

        return_response(false, false, "Update Key is not an array");
    }

    $update_keys = $_POST['update_key'];
    $update_values = $_POST['update_value'];

    $key_length = count($update_keys);

    $ret_data = $base_data; // $base_data is JSON from file that you want to update

    for($i=0; $i<$key_length; $i++){

        $ret_data[$update_keys[$i]] = $update_values[$i];

    }

    $ret_data = json_encode($ret_data, JSON_PRETTY_PRINT);
    if(file_put_contents('data.json', $ret_data)){

        return_response(true, false, "Data file updated");

    }

    return_response(false, false, "Error while updating data file");

}`

`

function return_response($success = true, $reload = false, $msg = ""){

    echo json_encode
    ( 
        [
            "success"=>$success,
            "msg"=> $msg,
            "reload"=> $reload
        ]
    );

    exit;

}`

jQuery部分:

`

$("button").click(function(){
    let inputs_array = $(this).data("inputs").split(",");
    var input_value = "";

    var post_input_keys = [];
    var post_input_values = [];

    for(var i = 0; i < inputs_array.length; i++){
        
            input_value = $("#"+inputs_array[i]).val(); 
            post_input_keys[i] = inputs_array[i];
            post_input_values[i] = input_value;

        }

        send_ajax_data(post_input_keys, post_input_values);

    });`

`

function send_ajax_data(update_key = [], update_value = []){

    $.ajax({
        type : "POST",
        url : "path_to_php_file.php",
        data : {
            update_data_file: 1,
            update_key: update_key,
            update_value: update_value
        },
        dataType : 'json',
        success : function(data) {
            console.log(data.msg);
        }
    });

}`

HTML:

`

<form id="fill_details_form" class="form" action="" method="post">
    <input type="hidden" name="update_data_file" value="1" />

    <div class="row mt-3">
                <div class="col-sm-3">
                    <div class="form-group">
                        <label for="form_name">Logo Width</label>
                        <input type="text" class="form-control" id="logo_width" name="logo_width" value="" />
                        <div class="help-block with-errors"></div>
                    </div>
                </div>

                <div class="col-sm-3">
                    <div class="form-group">
                        <label for="form_name">Logo Height</label>
                        <input type="text" class="form-control" id="logo_height" name="logo_height" value="" />
                        <div class="help-block with-errors"></div>
                    </div>
                </div>

                <div class="col-sm-3">
                    <label for="form_name"></label>
                    <div class="form-group">
                        <button 
                            type="button" 
                            id="update_logo_dims" 
                            class="btn btn-primary"
                            data-inputs="logo_width,logo_height"
                        >
                            Update logo width and height
                        </button>
                    </div>
                </div>
            </div>
</form>

`

data.json 示例:

`

{
"logo_file_name": "favicon.png",
"logo_width": "153",
"logo_height": "36",
"logo_url": "https:\/\/google.com?logourl",
"website_url": "https:\/\/google.com",
"website_title": "WEbsite Title",
"favicon_file_name": "favicon.PNG",

}

`

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM