一种更简单的方法,可以删除第一次出现字符之前的所有内容(包括字符)


A simpler way to remove everything before and including the first occurrence of character?

正如标题所说,这更令人感兴趣,实际上,我有1347020478_Workbook1 12.19.19.csv格式的文件名-我想做的是将时间戳从文件名的开头移开,并返回其他所有内容,因此Workbook1 12.19.19.csv

我有以下代码,它工作得很好:

$original_filename = explode('_', $list->file);
$timestamp         = array_shift($original_filename);
$original_filename = implode('_', $original_filename);

正如我所说,上面的代码是有效的,但我想知道是否有更简单的方法?

您可以使用stristr()ltrim()的组合来避免生成数组:

$original_filename = ltrim(stristr($list->file, '_'), '_');

请参阅手册:stristr返回从第一次出现针到最后的所有草垛。

您可以使用字符串函数,如strpos()substr():

$original_filename = '1347020478_Workbook1 12.19.19.csv';
echo substr( $original_filename, strpos( $original_filename, '_') + 1);

如果知道长度是固定的,就可以使用substr。如果没有,可以先使用strpos。以下给出了固定长度"子串"方法的1-2ms、"移位内爆"方法的4ms和可变长度"子"方法的1-2-ms。(如果我把数组做得更大,它就会耗尽内存,但你会明白的。)

$loops=1000000;
$filename="1347020478_Workbook1 12.19.19.csv"; 
for ($i=0;$i<$loops;$i++){
    $fn[$i]=$filename;
}
$start1=time();
for ($i=0;$i<$loops;$i++){
    $newname=substr($fn[$i],11);    
}
$end1=time();
echo $newname." time=".($end1-$start1)."<br><br>";

$filename="1347020478_Workbook1 12.19.19.csv"; 
for ($i=0;$i<$loops;$i++){
    $fn[$i]=$filename;
}
$start1=time();
for ($i=0;$i<$loops;$i++){
    $original_filename  = explode('_', $fn[$i]);
    $timestamp          = array_shift($original_filename);
    $original_filename  = implode('_', $original_filename);    
}
$end1=time();
echo $original_filename." time=".($end1-$start1)."<br><br>";

$filename="1347020478_Workbook1 12.19.19.csv"; 
for ($i=0;$i<$loops;$i++){
    $fn[$i]=$filename;
}
$start1=time();
for ($i=0;$i<$loops;$i++){
    $st=strpos($fn[$i],"_");
    $newname=substr($fn[$i],$st+1);    
}
$end1=time();
echo $newname." time=".($end1-$start1);

利用时间戳在很长一段时间内都是固定长度的事实,只要您的所有时间戳都位于2001年9月9日太阳01:46:40 GMT和2286年11月20日星期六17:46:39 GMT之间,最简单的方法是:

$original_filename = substr($list->file, 11);

try:

preg_replace('/^[0-9]+_/', '', $filename);

对于文件名列表foreach,执行preg_replace。同样的结果,少了2步。