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

Sorry, but I've got another newbie question. I need a regex to remove the path from a filename uploaded from a browser. It would look something like this: c:\windows\desktop\pic3.jpg or A:\pic3.jpg or something like that, and all I need is the following part: pic3.jpg. The one I made looks like this: s/.:\\.*\\//; but it doesn't work with files coming from a floppy. Any help would be appreciated.

Replies are listed 'Best First'.
Re: Quick Regex question
by Fastolfe (Vicar) on Jan 14, 2001 at 00:18 UTC
    You might want to leave the job of parsing the filename up to File::Basename:
    $full_path ='A:\dir\file.jpg'; $filename = basename($full_path); # file.jpg
(Ovid) Re: Quick Regex question
by Ovid (Cardinal) on Jan 14, 2001 at 00:20 UTC
    You can also try the following:
    my ( $filename ) = ( $path =~ /(\w+(?:\.\w+)?)$/ );
    The 'optional' section at the end is there because someone may upload a file without an extension.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Quick Regex question
by Coyote (Deacon) on Jan 14, 2001 at 00:25 UTC
    use strict; use warnings; my @path = split(/\\/, "c:\\windows\\desktop\\pic3.jpg"); print pop(@path);

    Note the escaped "\" character.

    ----
    Coyote

Re: Quick Regex question
by Chady (Priest) on Jan 14, 2001 at 00:53 UTC
    wouldn't a split just do it???

    @pathtofile = split(/\\/, $path); $file = pop(@pathtofile); $path here can be parsed from the form


    Chady | http://chady.net/

      A split will only work, if the filename is delimited by a backslash ('\'). Under DOS/Windows, there is still the nasty and often overlooked possibility of having a filename like c:myfile.ext, which is a valid filename, meaning a file on the drive c: in the current directory for drive c:.

      So the split should at least be on [\\:], but if we want real portability, I second the use of File::Basename, which is in the standard Perl distribution.

Re: Quick Regex question
by Stamp_Guy (Monk) on Jan 14, 2001 at 03:05 UTC
    I tried File:Basename, but it didn't do any better than my own regex at removing the path when it was uploaded from a floppy. So long as it is off of C:\, then everything works fine. What's up???
      Another function is splitpath from File::Spec.
      use File::Spec; ($volume,$directories,$file) = File::Spec->splitpath( $path ); # process $file
      This will of course work for / (unix), \ (win) and : (mac), unlike your regex. Still so should File::Basename.
      (fastolfe) gemina:~$ cat test use File::Basename; fileparse_set_fstype('MSWin32'); # Because I'm on Unix while (<DATA>) { chomp; printf("%20s %s\n", $_, basename($_)); } __DATA__ a:\pic3.jpg a:\some\dir\pic.jpg a:\some\other\pic \blah\pic. a:\pic a:pic.jpg a:\pic3. (fastolfe) gemina:~$ perl test a:\pic3.jpg pic3.jpg a:\some\dir\pic.jpg pic.jpg a:\some\other\pic pic \blah\pic. pic. a:\pic pic a:pic.jpg pic.jpg a:\pic3. pic3.
      So if File::Basename is working properly, perhaps your input is messed up somehow? Are you reading your filenames from a file perhaps and forgetting to chop off the newline?
        Let me explain in a little more detail what I'm trying to do. I have a form that writes to a text database. In that form, I have file upload fields that are used solely to get filenames for a photographic tour. When the names are written to the database, they have to have their paths chopped off. Those upload fields don't upload images because I couldn't get an upload script working that would upload that many images at once... The filenames are written to a text file (after having their paths chopped off) that tells what files need to be uploaded. Any path works so long as it has some folder in the path. Eg: A:\pic3.jpg would not work, whereas A:\test\pic3.jpg would.
      What was the path when it was uploaded from a floppy?
      Duplicate post.