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

Hi everyone !!

Here is an easy one for you !

I have a path to a file like this : "D:\My Documents\Document.txt" and I want to get only the part with "D:\My Documents". Right now I am doing this, but it does not seem quite efficient:
my $path = "D:/a directory/another directory/.../a file"; my @tmp = split(/\//, $path); my $last = @tmp - 1; $path =~ /\/$tmp[$last]/; my $dir = $PREMATCH; my $fileName = $tmp[$last];
It works but I feel I could use a regex for it instead of a split, or maybe something else than using a match.
So, the question is: is there a way to match only the last occurence of a character (like "/") in a string or any better way to get the directory of the file path?

All ideas are welcomed !

Replies are listed 'Best First'.
Re: match only last character of a kind
by samtregar (Abbot) on Aug 17, 2006 at 18:57 UTC
    Use File::BaseName. Example:

    use File::Basename; my ($filename, $dir, $suffix) = fileparse($path); print "The directory is: $dir\n";

    For more complex path-spliting, check out File::Spec.

    -sam

      Or just:
      use File::Basename; my $dir = dirname $path; print "The directory is: $dir\n";
      Another reason for using File::Basename instead of a RE is that it will change the dir separator to the appropriate slash from backslash when you move from Windows to *nix.

      Update: I mention this in particular because the slashes are going one direction in the OP text and the other way in the code section of the OP. (It can be quite quite hard to keep straight.)

        So it is portable.. which is good, the script I am writing will always run on windows because it is modifying the registry but leave some space to change. :)
Re: match only last character of a kind
by GrandFather (Saint) on Aug 17, 2006 at 19:42 UTC

    You have had your question answered. For reference, an answer to your title "match only last character of a kind" is to use a greedy match:

    my ($dir, $name) = $path =~ m|(.*/)(.*)|;

    DWIM is Perl's answer to Gödel
Re: match only last character of a kind
by sgifford (Prior) on Aug 17, 2006 at 19:48 UTC
    As others have said, File::Basename is definitely the right way to go for this particular problem.

    In general, though, you can do this sort of thing with a regular expression by using a character class that doesn't include the seperator. For example:

    if ($path =~ m|^(.*)/[^/]*$|) { $dir = $1; }
    will grab everything up to the last slash.
      Thanks ! I will try File::Basename.
        Well, thanks for all the information. I have used File::Basename and it works magnificiently for what I want to do. But I will also keep the other solution in mind, I need to match last occurences also. :) And sorry about the title, I kind of ask two questions at once.