Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I always stumble with this regex.

I need to extract a file name from a path (i.e.

/usr/local/bin/foo How can I grab 'foo' from the path?
Thanks

Replies are listed 'Best First'.
•Re: Simple Regex needed
by merlyn (Sage) on May 08, 2003 at 18:19 UTC
      Just for completeness, the way I've been doing it (because I didn't know about File::Basename either) is this:
      my ( $basename ) = reverse split /\//, "/tmp/app/foo";

      Now I'm going to go back and change my code to use File::Basename. Thanks, merlyn!

      --
      Spring: Forces, Coiled Again!
        > my ( $basename ) = reverse split /\//, "/tmp/app/foo";

        The only problem with this is that it's not portable: it'll work on Unix, but probably not on MS Windows.
Re: Simple Regex needed
by theorbtwo (Prior) on May 08, 2003 at 18:29 UTC

    There are two simple ways of answering this question. One is to give you what you asked for: a regex to get the filename component from a UNIX-style path. That regex is m|(.[^/]+)$/ (Read: a bunch of non-slash characters (the maximum number possible, more or less), then the end of the string (with various caveats on exactly what the end of string means).

    The other is to inform you of the right way to do it, which is to use File::Basename, which will do the right thing regardless of platform, and also makes the intent of your code more clear.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

      theorbtwo wrote: >  That regex is m|(.[^/]+)$/

      Thanks for that answer, which I think is correct in several respects (including the way it provides a direct answer to the question as originally posed alongside the statement of fact that there might be an easier way to do the job).

      The one thing I would point out is that maybe you meant to say:

       m|(.[^/]+)$| -or-

       /(.[^/]+)$/

      ...All the world looks like -well- all the world, when your hammer is Perl.
      ---v

Re: Simple Regex needed
by talexb (Chancellor) on May 08, 2003 at 18:31 UTC

    With $path = "/usr/local/bin/foo" ..

    • my $foo = ( split ( "/", $path ) )[ -1 ];
    • my $foo = ( $path =~ m"/(\w+)$" )[ 0 ];
    • There are also modules that will take care of this for you .. File::Spec is one of them.

    --t. alex
    Life is short: get busy!
Re: Simple Regex needed
by artist (Parson) on May 08, 2003 at 18:19 UTC
Re: Simple Regex needed
by Huele-pedos (Acolyte) on May 08, 2003 at 22:54 UTC
    $ perl -MFile::Basename -e'$f="/usr/local/bin/foo"; print basename( $ +f );' foo