Cách xóa phần mở rộng khỏi chuỗi (chỉ phần mở rộng thực!)


135

Tôi đang tìm kiếm một chức năng nhỏ cho phép tôi loại bỏ phần mở rộng khỏi tên tệp.

Tôi đã tìm thấy nhiều ví dụ bằng cách googling, nhưng chúng rất tệ, vì chúng chỉ xóa một phần của chuỗi bằng "." . Họ sử dụng dấu chấm cho bộ giới hạn và chỉ cắt chuỗi.

Nhìn vào các kịch bản này,

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

hoặc là

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

Khi chúng ta thêm chuỗi như thế này:

Đây là ví dụ về việc thuần hóa

Nó sẽ chỉ trả về "Cái này" ...

Tiện ích mở rộng có thể có 3 hoặc 4 ký tự, vì vậy chúng tôi phải kiểm tra xem dấu chấm có ở vị trí 4 hoặc 5 không, sau đó xóa nó.

Nó được hoàn thiện bằng cách nào?


1
Một phần mở rộng "thực sự" là gì? Bạn muốn loại bỏ 4 ký tự hoặc les cuối cùng nếu chúng được đặt trước bởi một dấu chấm?
clyfe

"Col. Shrapnel" - nó được thiết kế cho người dùng Windows. "clyfe" - vâng, tôi muốn xóa mọi thứ sau dấu chấm, nhưng chỉ khi ở vị trí 4 hoặc 5, cái gì sẽ đại diện cho ".jpeg" hoặc ".mp3". Tôi sẽ không loại bỏ nó. Tôi biết tôi có thể thực hiện thủ công bằng cách sử dụng str-pos và cắt chuỗi bằng cách sử dụng câu lệnh if (if 5 pos = dot sau đó cắt (rtrim) từ 5 ký tự bên phải, nếu 4 pos = dot thì rtrim 4, khác sẽ trả về mà không cần sửa đổi. Nhưng có lẽ đó là giải pháp nhanh hơn.
marc

3
Những gì về tập tin .package? Hay .unity? Có vẻ một chút tùy ý để hạn chế một phần mở rộng thành 4 ký tự.
rdb

Câu trả lời:


172

Hãy thử cái này:

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

Vì vậy, cái này khớp với một dấu chấm theo sau bởi ba hoặc bốn ký tự không phải là dấu chấm hoặc dấu cách. Quy tắc "3 hoặc 4" có lẽ nên được nới lỏng, vì có rất nhiều phần mở rộng tệp ngắn hơn hoặc dài hơn.


vấn đề là cũng có những người đổi tên các tập tin như:20120720.something.somethingelse.jpg
Obmerk Kronen

3
Tôi không nghĩ rằng điều này sẽ hoạt động với các tệp có hai ký tự như một phần mở rộng
NaturalBornCamper

1
ty! xin vui lòng lưu ý rằng bạn nên sử dụng dấu nháy đơn nếu bạn không thực hiện thay biến ví dụ"$var"
aelgoa

tốt, để sử dụng nó với các tệp .py tôi đoán bạn phải thêm 2,3,4 thay vì chỉ 3,4:> cảm ơn!
voghDev

2
@voghDev để hỗ trợ các tiện ích mở rộng có từ 2 đến 4 ký tự bạn nên thêm {2,4}thay vì{3,4}
Timo Huovinen


81

Từ hướng dẫn, pathinfo :

<?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
?>

Nó không phải là một con đường hoàn chỉnh để hoạt động đúng. Nó sẽ chỉ là hạnh phúc phân tích file.jpgnhư /path/to/my/file.jpg.


Tôi đã kiểm tra điều này. Lỗi tương tự như trên. Hãy thử truy cập "$ path_parts ['filename']" từ T.sec - "xxx" 23 12 32 3 một twym2 Nó sẽ chỉ trả về T. Từ ví dụ trên, nó không nên xóa bất cứ điều gì!
marc

56

Sử dụng tên cơ sở PHP ()

(PHP 4, PHP 5)

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

Đầu ra: chuỗi (4) "kiểm tra"


2
+1 Nếu các yêu cầu được đề cập cho một tiện ích mở rộng không nghiêm ngặt, đây sẽ là câu trả lời hoàn hảo.
Kayla

1
Nhìn vào các cam kết trên php.net, có một ý tưởng về việc làm việc với một mảng ... mà tôi nghĩ có thể được cải thiện bằng cách sử dụng một cái gì đó như mảng đi bộ
CrandellWS

35

Đây là một giải pháp khá dễ dàng và sẽ hoạt động cho dù mở rộng bao lâu hoặc có bao nhiêu dấu chấm hoặc các ký tự khác trong chuỗi.

$filename = "abc.def.jpg";

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

//$newFileName will now be abc.def

Về cơ bản điều này chỉ tìm kiếm sự xuất hiện cuối cùng của. và sau đó sử dụng chuỗi con để lấy tất cả các ký tự cho đến thời điểm đó.

Nó tương tự như một trong những ví dụ được cho là của bạn nhưng đơn giản hơn, nhanh hơn và dễ dàng hơn các biểu thức thông thường và các ví dụ khác. Vâng imo nào. Hy vọng nó sẽ giúp được ai đó.


2
Tôi biết điều này đang đến quá muộn, nhưng tôi nghĩ đây là câu trả lời tốt nhất. Công trình tuyệt vời.
Agbogidi Michael

điều này sẽ không hoạt động đối với các tệp ẩn * nix mà không có phần mở rộng, chẳng hạn,.htaccess
Fr0zenFyr

12

Bạn có thể sử dụng những gì PHP đã tích hợp để hỗ trợ ...

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

Mặc dù nếu bạn chỉ xử lý một tên tệp ( .somefile.jpg), bạn sẽ nhận được ...

./somefile

Xem nó trên CodePad.org

Hoặc sử dụng regex ...

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

Xem nó trên CodePad.org

Nếu bạn không có đường dẫn, nhưng chỉ cần một tên tệp, nó sẽ hoạt động và trở nên phức tạp hơn ...

$withoutExt = pathinfo($path, PATHINFO_FILENAME);

Xem nó trên CodePad.org

Tất nhiên, cả hai chỉ tìm kiếm khoảng thời gian cuối cùng ( .).


Như đã đề cập ở dòng giải pháp cuối cùng, nó sẽ thất bại đối với các tên tệp như.htaccess
Fr0zenFyr

8

Đoạn mã sau hoạt động tốt với tôi và nó khá ngắn. Nó chỉ chia tập tin thành một mảng được giới hạn bởi các dấu chấm, xóa phần tử cuối cùng (theo giả thuyết là phần mở rộng) và cải tổ lại mảng với các dấu chấm một lần nữa.

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

sẽ trả về false nếu tệp không có phần mở rộng hoặc trống nếu tệp là.htaccess
Timo Huovinen

5

Tôi đã tìm thấy nhiều ví dụ trên Google nhưng có lỗi vì chỉ xóa một phần của chuỗi bằng "."

Trên thực tế đó là điều hoàn toàn chính xác để làm. Đi trước và sử dụng đó.

Phần mở rộng tệp là tất cả mọi thứ sau dấu chấm cuối cùng và không có yêu cầu đối với phần mở rộng tệp là bất kỳ số lượng ký tự cụ thể nào. Ngay cả khi chỉ nói về Windows, nó đã đi kèm với các phần mở rộng tệp không phù hợp với 3-4 ký tự, chẳng hạn như. .manifest.


2
..và đừng quên .htaccess.htpasswdtrong môi trường apache.
h2ooooooo

5

Đề nghị sử dụng: pathinfo với PATHINFO_FILENAME

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

4

Có một vài cách để làm điều đó, nhưng tôi nghĩ một trong những cách nhanh hơn là sau đây

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

Một giải pháp khác là điều này. Tôi chưa thử nghiệm nó, nhưng có vẻ như nó sẽ hoạt động trong nhiều thời gian trong một tên tệp

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

Cũng thế:

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

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

Trong tất cả những thứ này, $namechứa tên tệp mà không có phần mở rộng


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

Đầu ra:

this-is.file.name

1
$the_extension = substr($image_name, $last_dot_index, $last_dot_index);Thêm vào đó để có được phần mở rộng của tập tin.
I_ATE_YOUR_WORK_FILES

2

Như những người khác đề cập, ý tưởng giới hạn mở rộng cho một số lượng ký tự nhất định là không hợp lệ. Với ý tưởng về Array_pop, nghĩ về một chuỗi được phân tách thành một mảng, hàm này rất hữu ích với tôi ...

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

Sử dụng:

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

Đầu ra:

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

Trong hành động:

http://sandbox.onlinephpfifts.com/code/5d12a96ea548f696bd097e2986b22de7628314a0


1

Bạn có thể đặt độ dài của mẫu biểu thức chính quy bằng cách sử dụng {x,y}toán tử.{3,4}sẽ phù hợp nếu mô hình tiền xử lý xảy ra 3 hoặc 4 lần.

Nhưng tôi không nghĩ rằng bạn thực sự cần nó. Bạn sẽ làm gì với một tập tin có tên "This.is"?


0

Dùng cái này:

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

Điều này chỉ hoạt động nếu tên tệp chưa có dấu chấm. Tài liệu PHP đề cập đến sự xuất hiện đầu tiên của kim
tái hiện

0

Hãy thử sử dụng cái này. Nó chắc chắn sẽ loại bỏ phần mở rộng tập tin.

$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'

Bạn có thể giảm số dòng này xuống một dòng với mảng_pop ()
Peter Brand

0

EDIT : Cách tiếp cận thông minh nhất IMHO, nó loại bỏ điểm cuối cùng và văn bản sau khỏi tên tệp (còn gọi là phần mở rộng):

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

Chúc mừng;)


Trong khi nó có thể hoạt động, end()không phải hoạt động với một hàm được truyền dưới dạng tham số. Nó cũng tạo ra một thông báo: Chỉ các biến nên được chuyển qua tham chiếu
CodeBrauer

0

Điều này hoạt động khi có nhiều phần cho một phần mở rộng và vừa ngắn vừa hiệu quả:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.