将文本添加到特定行而不删除 php 中的现有行

Add text to specific line without removing the exist line in php

如果名字相同,我将尝试仅添加姓氏

data.txt

Alice Sandy
Alice Nanami
James Watt
Alice Monica
Johann Gauss

到result.txt

Alice Sandy Nanami Monica
James Watt
Johann Gauss

我试试这个代码

$resultFile = "result.txt";
$search     = "Alice";
$lineNumber = false;
if ($handle = fopen($result, "r")) {
    $count = 0;
    while (($line = fgets($handle, 4096)) !== FALSE and !$lineNumber) {
        $count++;
        $lineNumber = (strpos($line, $search) !== FALSE) ? $count : $lineNumber;
        $isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";
    }
fclose($handle);
}
if($isExist=="yup"){
    $lines = file($resultFile);
    $lines[$lineNumber] = $lines[$lineNumber].' '.$lastName;
    file_put_contents($result, implode('', $lines));
}else{
    $fullName = $firstName.' '.$lastName;
    $fileOpen = fopen($result, "a");
    fwrite($fileOpen,$fullName);
    fclose($fileOpen);
    $addBreaker = "\n";
    $splResult = new SplFileObject($resultFile, 'a');
    $splResult->fwrite($addBreaker);
}

但它给出了错误偏移量(我使用的是 PHP 7)并且结果不整洁

Alice Sandy Nanami
 Monica
James Watt

Johan Gauss

感谢帮助

另一种替代行的方法是将每一行保存到一个数组,然后遍历数组并保存到新文件。您还可以使用与 $outputFile.

相同的文件
$inputFile = 'names.txt';
$outputFile = 'result.txt';

$names = [];

if ($handle = fopen($inputFile, "r")) {
    $count = 0;
    while (($line = fgets($handle, 4096)) !== FALSE) {
        $count++;
        $lineNames = explode(' ', $line);
        $names[$lineNames[0]][] = trim($lineNames[1]);
    }
    fclose($handle);
}

$handle = fopen($outputFile, 'w');
foreach ($names as $firstName => $lastNames) {
    fwrite($handle, $firstName . ' ' . implode(' ', $lastNames) . PHP_EOL);
}

两个补充说明:

  1. 不要使用字符串作为布尔值。

    $isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";

只使用以下条件。够了

$isExist = (strpos($line, $search) !== FALSE)
  1. 如果您从文件中读取行,您也会复制新行 char,尽管您在输出中看不到它们。您应该 trim 在 inserting/replacing 等之前的所有空白字符,以避免文件的旧结构。

使用file()将文件内容收集为行数组。我的代码片段从那里开始 $lines.

迭代数组并使每一行都可以通过引用进行修改。 (&)

找到第一个出现的针匹配,它不仅存在于行中而且匹配整个第一个单词,这样您就不会得到误报匹配。

然后将第一个匹配项声明为引用变量(=&)并继续迭代数组。任何后续匹配项都会将分隔符 space 和第二个单词附加到引用变量。然后立即取消设置要从文档中清除的行。

完成后,重新内爆数据并将内容填充到结果文件中。

这是干净的,可读的,只需要一个循环。

代码:(Demo)

// $lines = file('result.txt', FILE_IGNORE_NEW_LINES);
$lines = [
    'Alice Sandy',
    'Alice Nanami',
    'James Watt',
    'Alice Monica',
    'Johann Gauss',
    'Cooper Alice',
];

$needle = 'Alice';
foreach($lines as $index => &$line) {
    if ($needle === strstr($line, ' ', true)) { // check whole first word
        if (!isset($firstOccurrence)) {
            $firstOccurrence =& $line;
        } else {
            $firstOccurrence .= strstr($line, ' ');
            unset($lines[$index]);
        }
    }
}
var_export($lines);
// file_put_contents('result.txt', implode(PHP_EOL, $lines));

输出:

array (
  0 => 'Alice Sandy Nanami Monica',
  2 => 'James Watt',
  4 => 'Johann Gauss',
  5 => 'Cooper Alice',
)

P.s 如果你想知道是否有任何行被更改,你可以检查原始数组是否是 === 循环后的新数组,或者你可以在else条件。