PHP:删除文本的第一行并返回其余部分

30

如何在PHP中删除文本字符串的第一行并输出其余部分?

例如:

这是文本字符串:

$t=<<<EOF
First line to be removed
All the rest
Must remain
EOF;

这是最终输出结果:

All the rest
Must remain

如果我要在Bash中处理一个文件,我可以轻松地执行以下操作:

sed -i~ 1d 目标文件

或者:

tail -n +2 源文件 > 目标文件

有任何想法吗?

8个回答

49

除了其他回答中使用explodeimplode或正则表达式外,您还可以使用strpos()substr()

function stripFirstLine($text) {        
  return substr($text, strpos($text, "\n") + 1);
}
echo stripFirstLine("First line.\nSecond line.\nThird line.");        

实时示例:http://codepad.org/IoonHXE7


你在我刚要在答案中添加同样内容之前就完成了这个。+1 - Michael Berkowski
你在 Codepad 上的实时速度测试示例存在严重的错误。在第二次运行中,你的 $n 没有被正确初始化。它必须是:$n = $count; 因此,它只比原来快了 2 倍,而不是 6 倍。 - Jan
@Jan 感谢您的关注!九年后,我也意识到微基准测试的陷阱。现在我已经删除了有关性能的注释。 - ComFreek

32

preg_replace怎么样:

$text = "First line.\nSecond line.\nThird line.";
echo preg_replace('/^.+\n/', '', $text);
这样做,你就不必担心文件中没有换行符的情况。 http://codepad.org/fYZuy4LS

这完全取决于情况,它是其他解决方案的一个不错的替代选择。 - matino
2
请注意,由于您使用了贪婪量词和 .(匹配所有字符),因此您将仅获取最后一行,而不是除第一行以外的所有内容。您应该使量词变得不贪婪,即:/^.+?\n/ - PatrikAkerstrand
@PatrikAkerstrand Dot 不匹配 \n,所以不是这种情况。 - Paul
preg 使得代码难以维护,因为很多边缘(以及有经验的)程序员不理解它。 - Danial
@ComFreek:事实证明,PHP中的preg_replace并不慢,我对这里所有答案的解决方案进行了基准测试:http://codepad.org/xt9kK2E2 - Jan

8

explode() 将文本按照换行符拆分成数组,shift() 取出第一行并删除,然后将剩余部分重新组合。

$arr = explode("\n", $t);
array_shift($arr);
echo implode("\n", $arr);

// Prints
// All the rest
// Must remain

如果你的字符串非常大,这将会占用大量内存。但如果你的字符串与示例相当,那么它将可以正常工作。
方法2,使用 strpos()
echo substr($t, strpos($t, "\n") + 1);

7
我知道这是一个晚回答,但为什么你不使用explode函数并限制结果数量呢?
$parts = explode("\n", $test, 2);
//$parts[0] has the first line
//$parts[1] has everything else

2

我尝试了所有这些方法,但对于大文件(50MB+),它们似乎都不够快。以下是我创建的解决方案。在您的情况下,您可以省略第一行的echo。

最初的回答:

$fh = fopen($local_file, 'rb');
echo "add\tfirst\tline\n";  // add your new first line.
fgets($fh); // moves the file pointer to the next line.
echo stream_get_contents($fh); // flushes the remaining file.
fclose($fh);

2
更灵活的解决方案是,您可以使用一个分隔符从字符串str中删除num行,并返回其余部分。
默认的seperator\n。如果要使用不同的seperator,请在调用striplines()函数时使用第三个参数。
function striplines($str,$num,$seperator="\n"){
    $arr = explode($seperator, $str);
    for ($i=0;$i<$num;$i++) array_shift($arr);
    return implode($seperator, $arr);
}

//Testcases to remove first two lines
// returns/prints only Third line
echo striplines("First line.\nSecond line.\nThird line.",2); 

// returns/prints nothing
echo striplines("First line.\nSecond line.\n",2); 
echo striplines("First line.\nSecond line.",2);
echo striplines("First line.\n",2);
echo striplines("First line.",2);
echo striplines("",2);

1

返回第一个换行符后面的子字符串:

$firstLineRemoved = $subject;
$firstNewlinePosition = strpos($subject, "\n");
if($firstNewlinePosition !== false)
{
  $firstLineRemoved = substr($subject, firstNewlinePosition +1);
}
echo $firstLineRemoved;

编辑:与@ComFreek相同的示例,但在没有换行符的情况下进行错误检查


0
所有的答案都是低效的。没有必要使用任何函数来操作字符串。
$pos = 0;
while ($str[$pos] !== PHP_EOL)
    $str[$pos++] = '';
echo $str;

如果您不确定字符串是否始终包含多行,请使用以下内容:

if (strpos($str, PHP_EOL))
{
    $pos = 0;
    while ($str[$pos] !== PHP_EOL)
        $str[$pos++] = '';
    echo $str;
}

@aefxx 当然我仍在操作字符串。我从未说过我不是,我只是说没有必要使用任何函数来操作字符串。 - Dan Bray
这并不是必要的。然而,学习的好处在于函数中所包含的内容。我通常会将代码提取出来并内联解决方案。这样可以减少开销。封装解决方案可以学习到SO中散布的不同方法。 - WiiLF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接