如何从字符串中删除扩展名(只删除真正的扩展名!)

我正在寻找一个小函数,允许我删除文件名的扩展名。

我通过谷歌找到了很多例子,但是它们都很糟糕,因为它们只是删除了字符串的一部分.他们用点来限制,只是切断线。

看看这些剧本,

$from = preg_replace('/\.[^.]+$/','',$from);

或者

 $from=substr($from, 0, (strlen ($from)) - (strlen (strrchr($filename,'.'))));

当我们像这样添加字符串时:

这是一个字符串的例子

它只会返回“这个”..。

扩展名可以有3或4个字符,所以我们必须检查点是在4或5位置,然后删除它。

怎样才能做到呢?

215079 次浏览

可以使用 {x,y}运算符设置正则表达式模式的长度。如果前面的模式出现3或4次,则 {3,4}将匹配。

但我不认为你真的需要它。你将如何处理一个名为“ This. is”的文件?

根据手册 返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返回文章页面返:

<?php
$path_parts = pathinfo('/www/htdocs/index.html');


echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n"; // Since PHP 5.2.0
?>

它不必是一个完整的路径才能正确操作,它将像解析 /path/to/my/file.jpg一样快乐地解析 file.jpg

试试这个:

$withoutExt = preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);

所以,这匹配了一个点后面跟着三个或四个字符,而这些字符既不是点也不是空格。“3或4”规则可能应该放宽,因为有大量的文件扩展名更短或更长。

我在 Google 上找到了很多例子,但是也有不好的例子,因为只要删除字符串的一部分就可以了

事实上,这绝对是正确的做法。继续使用它。

文件扩展名就是最后一个点之后的所有内容,并且没有要求文件扩展名必须是任何特定数量的字符。即使只谈到 Windows,它已经提供了不适合3-4个字符的文件扩展名,例如。.manifest.

您可以使用 PHP 内置的功能来帮助..。

$withoutExt = pathinfo($path, PATHINFO_DIRNAME) . '/' . pathinfo($path, PATHINFO_FILENAME);

尽管如果您只处理一个文件名(.somefile.jpg) ,您将得到..。

./some file

可以在 CodePad.org 上看到

或者使用正则表达式。

$withoutExt = preg_replace('/\.' . preg_quote(pathinfo($path, PATHINFO_EXTENSION), '/') . '$/', '', $path);

可以在 CodePad.org 上看到

如果您没有一个路径,但只有一个文件名,这将工作和更简洁..。

$withoutExt = pathinfo($path, PATHINFO_FILENAME);

可以在 CodePad.org 上看到

当然,这两者都只是寻找最后一个周期(.)。

使用 PHP basename ()

(PHP4,PHP5)

var_dump(basename('test.php', '.php'));

输出: string (4)“ test”

下面的代码非常适合我,而且非常简短。它只是将文件分解成一个由点分隔的数组,删除最后一个元素(假设是扩展名) ,然后再次用点改变数组。

$filebroken = explode( '.', $filename);
$extension = array_pop($filebroken);
$fileTypeless = implode('.', $filebroken);

有几种方法可以做到这一点,但我认为其中一个更快的方法是以下

// $filename has the file name you have under the picture
$temp = explode( '.', $filename );
$ext = array_pop( $temp );
$name = implode( '.', $temp );

另一个解决方案是这样的。我还没有对它进行测试,但是看起来它应该可以在一个文件名中工作多个时段

$name = substr($filename, 0, (strlen ($filename)) - (strlen (strrchr($filename,'.'))));

另外:

$info = pathinfo( $filename );
$name = $info['filename'];
$ext  = $info['extension'];


// Or in PHP 5.4, i believe this should work
$name = pathinfo( $filename )[ 'filename' ];

在所有这些文件中,$name包含不带扩展名的文件名

用这个:

strstr('filename.ext','.',true);
//result filename

Http://php.net/manual/en/function.pathinfo.php

Pathinfo ー返回有关文件路径的信息

$filename = pathinfo('filename.md.txt', PATHINFO_FILENAME); // returns 'filename.md'

这是一个相当简单的解决方案,不管扩展名有多长,也不管字符串中有多少点或其他字符,它都能正常工作。

$filename = "abc.def.jpg";


$newFileName = substr($filename, 0 , (strrpos($filename, ".")));


//$newFileName will now be abc.def

基本上这只是寻找最后发生的。然后使用子字符串检索到该点的所有字符。

它类似于您在谷歌上搜索的一个示例,但是比正则表达式和其他示例更简单、更快、更容易。不管怎么说。希望能帮到别人。

尝试使用这一个。它一定会删除文件扩展名。

$filename = "image.jpg";
$e = explode(".", $filename);
foreach($e as $key=>$d)
{
if($d!=end($e)
{


$new_d[]=$d;
}


}
echo implode("-",$new_t);  // result would be just the 'image'

编辑: 恕我直言,最聪明的方法是从文件名(也就是扩展名)中删除 最后一点和后面的文字:

$name = basename($filename, '.' . end(explode('.', $filename)));

干杯;)

正如其他人提到的,将扩展限制在一定数量的字符是无效的。根据 array _ pop 的思想,将带分隔符的字符串想象成一个数组,这个函数对我很有用..。

function string_pop($string, $delimiter){
$a = explode($delimiter, $string);
array_pop($a);
return implode($delimiter, $a);
}

用法:

$filename = "pic.of.my.house.jpeg";
$name = string_pop($filename, '.');
echo $name;

产出:

pic.of.my.house  (note it leaves valid, non-extension "." characters alone)

实际行动:

Http://sandbox.onlinephpfunctions.com/code/5d12a96ea548f696bd097e2986b22de7628314a0

$image_name = "this-is.file.name.jpg";
$last_dot_index = strrpos($image_name, ".");
$without_extention = substr($image_name, 0, $last_dot_index);

产出:

this-is.file.name

当一个扩展包含多个部分,并且既简短又高效时,这种方法可以奏效:

function removeExt($path)
{
$basename = basename($path);
return strpos($basename, '.') === false ? $path : substr($path, 0, - strlen($basename) + strlen(explode('.', $basename)[0]));
}


echo removeExt('https://example.com/file.php');
// https://example.com/file
echo removeExt('https://example.com/file.tar.gz');
// https://example.com/file
echo removeExt('file.tar.gz');
// file
echo removeExt('file');
// file

推荐使用: pathinfo PATHINFO_FILENAME

$filename = 'abc_123_filename.html';
$without_extension = pathinfo($filename, PATHINFO_FILENAME);

在这个页面上着陆寻找 最快方法从 glob()结果中删除数字文件名中的扩展名。

因此,我做了一些非常基本的基准测试,发现这是最快的方法。这还不到 preg_replace()的一半时间:

$result = substr($fileName,0,-4);

现在我知道所有的文件在我的 glob()有一个 .zip扩展,所以我可以这样做。

如果文件扩展名未知且长度未知,则下面的方法可以工作,并且仍然比 preg_replace()快20% 左右。也就是说,只要有一个延期。

$result = substr($fileName,0,strrpos($fileName,'.'));

基本的基准测试代码和测试结果:

$start = microtime(true);


$loop = 10000000;
$fileName = 'a.LONG-filename_forTest.zip';
$result;


// 1.82sec preg_replace() unknown ext
//do {
//    $result = preg_replace('/\\.[^.\\s]{3,4}$/','',$fileName);
//} while(--$loop);


// 1.7sec preg_replace() known ext
//do {
//    $result = preg_replace('/.zip$/','',$fileName);
//} while(--$loop);


// 4.57sec! - pathinfo
//do {
//    $result = pathinfo($fileName,PATHINFO_FILENAME);
//} while(--$loop);


// 2.43sec explode and implode
//do {
//    $result = implode('.',explode('.',$fileName,-1));
//} while(--$loop);


// 3.74sec basename, known ext
//do {
//    $result = basename($fileName,'.zip');
//} while(--$loop);


// 1.45sec strpos unknown ext
//do {
//    $result = substr($fileName,0,strrpos($fileName,'.'));
//} while(--$loop);


// 0.73sec strpos - known ext length
do {
$result = substr($fileName,0,-4);
} while(--$loop);


var_dump($fileName);
var_dump($result);
echo 'Time:['.(microtime(true) - $start).']';


exit;