2011-01-22 6 views

Respuesta

24

¿Por qué reinventar la rueda? Utilice el módulo File::Basename:

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

¿Por qué no funciona $file=$path=~s/.*\///;?

=~ tiene mayor precedence que =

Así

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

se trata como:

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

que hace la sustitución en $path y asigna ya sea 1 (si se produce la sustitución) o '' (si no ocurre reemplazo).

Lo que queremos es:

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

que asigna el valor de $path a $file y luego se hace la sustitución en $path.

Pero de nuevo hay muchos problemas con esta solución:

  1. es incorrecto. Un nombre de archivo en sistemas basados ​​en Unix (no estoy seguro acerca de Windows) puede contener nueva línea. Pero . de forma predeterminada no coincide con una nueva línea. Por lo que usted tiene que utilizar un modificador s de manera que coincida con . nueva línea así:

    ($file = $path) =~s/.*\///s; 
    
  2. más importante es que no es portátil, ya que está asumiendo / es el separador de ruta que no es el caso de algunas plataformas como Windows (que usa \), Mac (que usa :). Entonces use el módulo y deje que maneje todos estos problemas por usted.

+1

acuerdo. Generalmente es mejor usar un módulo como este que una expresión regular, ya que es multiplataforma. – justintime

+1

También tenga en cuenta que File :: Basename es un módulo básico, y siempre ha estado en Perl 5 por lo que no necesita ser instalado. – mscha

+0

La página de manual sobre File :: Basename recomienda utilizar el método 'fileparse' para esta tarea, ya que" [basename] NO siempre devuelve la parte del nombre de archivo de una ruta como cabría esperar " – jutky

0

Path::Class puede parecer demasiado difícil al principio, haciendo que los objetos de archivo y rutas-pero dir se realmente puede pagar en scripts complicados y ofrece muchas bonificaciones que evitarán los espaguetis cuando te vean acorralado por el creeping del alcance. File::Spec se usa en el primer ejemplo para resolver la ruta de forma divertida.

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

Para una mejor publicación, puede ampliar su respuesta, explicando por qué esa expresión regular particular funcionaría para varios ejemplos. Esto ayudará a que su respuesta tenga sentido para el cartel original, y para los muchos otros lectores futuros. – Castaglia

1

creo que la mejor manera de hacer esto es -

use File::Basename; 

my $file_name = basename($0); 

Así la variable $file_name tendrá el nombre de su script

Cuestiones relacionadas