2011-01-22 37 views

Trả lời

24

Tại sao tái tạo bánh xe? Sử dụng các mô-đun File::Basename:

use File::Basename; 
... 
$file = basename($path); 

Tại sao $file=$path=~s/.*\///; không hoạt động?

=~ đã tăng precedence hơn =

Vì vậy

$file = $path =~s/.*\///; 

được xử lý như sau:

$file = ($path =~s/.*\///); 

mà làm việc thay thế trong $path và giao hoặc 1 (nếu thay thế xảy ra) hoặc '' (nếu không có thay thế xảy ra).

gì bạn muốn là:

($file = $path) =~s/.*\///; 

đó gán giá trị của $path-$file và sau đó thực hiện việc thay thế trong $path.

Nhưng một lần nữa có rất nhiều vấn đề với giải pháp này:

  1. Đó là không chính xác. Tên tệp trong các hệ thống dựa trên Unix (không chắc chắn về Windows) có thể chứa dòng mới. Tuy nhiên, . theo mặc định không khớp với dòng mới. Vì vậy, bạn sẽ phải sử dụng một modifier s để . phù hợp xuống dòng cũng như:

    ($file = $path) =~s/.*\///s; 
    
  2. Quan trọng nhất là nó không phải là xách tay vì nó là giả / là tách con đường mà không phải là trường hợp với một số nền tảng như Windows (sử dụng \), Mac (sử dụng :). Vì vậy, sử dụng các mô-đun và để cho nó xử lý tất cả những vấn đề này cho bạn.

+1

Đồng ý. Nói chung tốt hơn bằng cách sử dụng một mô-đun như thế này hơn là một regex vì nó là nền tảng chéo. – justintime

+1

Cũng lưu ý rằng File :: Basename là một mô-đun lõi và luôn nằm trong Perl 5 nên không cần phải cài đặt. – mscha

+0

Trang người đàn ông về File :: Basename, khuyến cáo sử dụng phương pháp 'fileparse' cho tác vụ này, vì" [tên cơ sở] KHÔNG luôn trả về phần tên tệp của đường dẫn như bạn mong đợi " – jutky

0

Path::Class có vẻ như quá mức cần thiết lúc đầu làm đối tượng của tập tin và đường dẫn-nhưng dir nó thực sự có thể trả hết trong các kịch bản phức tạp và cung cấp nhiều tiền thưởng sẽ ngăn chặn spaghetti khi bạn được sao lưu vào một góc bằng phạm vi creep. File::Spec được sử dụng trong ví dụ đầu tiên cho vui để giải quyết đường dẫn.

use warnings; 
use strict; 
use Path::Class qw(file); 
use File::Spec; 

# Get the name of the current script with the procedural interface- 
my $self_file = file(File::Spec->rel2abs(__FILE__)); 
print 
    " Full path: $self_file", $/, 
    "Parent dir: ", $self_file->parent, $/, 
    " Just name: ", $self_file->basename, $/; 

# OO          
my $other = Path::Class::File->new("/tmp/some.weird/path-.unk#"); 
print "Other file: ", $other->basename, $/; 
0
$url=~/\/([^\/]+)$/; 
print "Filename $1\n"; 
+2

Để tạo bài đăng tốt hơn, bạn có thể mở rộng câu trả lời của bạn, giải thích lý do tại sao regex cụ thể đó sẽ làm việc cho các ví dụ khác nhau. Điều này sẽ giúp câu trả lời của bạn phù hợp với áp phích gốc, _and_ cho nhiều độc giả khác trong tương lai. – Castaglia

1

Tôi nghĩ rằng cách tốt nhất để làm điều này là -

use File::Basename; 

my $file_name = basename($0); 

Vì vậy, các biến $file_name sẽ có tên của kịch bản của bạn

Các vấn đề liên quan