在php中添加文本到特定的行,而不需要删除已有的行。

问题描述 投票:1回答:1

如果名字相同,我想只加姓。

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

谢谢你的帮助

php php-7
1个回答
1
投票

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

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

找到第一个出现的针状匹配,它不仅存在于该行中,而且匹配了整个第一个词,这样就不会出现假阳性匹配。

然后将第一个匹配项声明为一个参考变量(=&)并继续迭代数组。 任何后续的匹配都会将分隔符和第二个字追加到引用变量中。 然后立即将要清除的行从文件中解集。

完成后,重新对数据进行迭代,并将内容塞进结果文件。

这样很干净,可读性强,而且只需要一个循环。

编码。(演示)

// $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 条件。


1
投票

另一种代替替换行的方法是将每行保存到一个数组中,然后在数组中迭代并保存到新的文件中。你也可以使用同一个文件作为 $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. 如果你从文件中读取行,你也会复制新的行,尽管你在输出中不能很好地看到它们。在插入、替换等操作之前,你应该修剪所有的空白字符,以避免文件的旧结构。
© www.soinside.com 2019 - 2024. All rights reserved.