[英]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 。
對於大文件,算法略有不同,但大致相同。
重要的部分是文件鎖定
這就是為什么我們更喜歡數據庫。
如果您不知道該行,則必須搜索所有行。
逐行遍歷文件或一次將文件全部讀入內存。 然后要么使用strpos
和str_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)));}}
我希望能回答你的問題:)
如果您在處理文件時不打算鎖定文件,那么
也就是說,為了速度而犧牲准確性是沒有意義的。 這個問題指出必須在該行中匹配一個單詞。 因此,必須防止部分匹配——正則表達式提供單詞邊界( \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.