如果名字相同,我想只加姓。
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
谢谢你的帮助
使用 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
条件。
另一种代替替换行的方法是将每行保存到一个数组中,然后在数组中迭代并保存到新的文件中。你也可以使用同一个文件作为 $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);
}
两个补充说明。
不要用字符串作为布尔值。
$isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";
只使用下面的条件。这就够了
$isExist = (strpos($line, $search) !== FALSE)