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

Hello fellow monks, I am hoping someone might know how to overcome the Win32 path backslash delimiter '\' in the following type of script.
my $file = 'c:/some/win32/path/mydir/file.txt';
my $path = 'c:/some/win32/path';

(my $file_nopath_noext = $file) =~ s/$path\/(.*)\.txt/$1/;
print $file_nopath_noext."\n";
This works fine but now replace forward slashes in the $file and $path variables to a backslash and it all stops working. How does one stop interpolation on the $path variable in s///? I've tried using (?{$path}) to no avail. I would prefer not to do any variable preprocessing.
  • Comment on how to overcome Win32 path delimiter in s///?

Replies are listed 'Best First'.
Re: how to overcome Win32 path delimiter in s///?
by The Mad Hatter (Priest) on Oct 14, 2004 at 23:32 UTC

    Wrap $path in \Q and \E (which escapes metachars) like so...

    my $file = 'c:\some\win32\path\mydir\file.txt'; my $path = 'c:\some\win32\path'; (my $file_nopath_noext = $file) =~ s/\Q$path\E\\(.*)\.txt/$1/; print $file_nopath_noext."\n";

    See perldoc perlre.

      that's precisely what I was hoping for. I failed to consider \Q..\E metacharacter manipulation. Thank you
        The function quotemeta will acomplish the same thing if you use it on the value before it is interpolated by the regex.

        If you are particularly worried about forward slashes then you can just use an alternate character to delimit the parts of the substitution.
        e.g. single char s!!! or paired s()()

Re: how to overcome Win32 path delimiter in s///?
by ikegami (Patriarch) on Oct 15, 2004 at 00:45 UTC

    File::Spec has functions to seperate parts, and function to make relative paths from absolute ones, all in an OS-independant manner:

    use File::Spec (); $file_nopath_noext = File::Spec->abs2rel($file, $path); $file_nopath_noext =~ s/\.\w*$//; # Chop extention if

    Keep in mind the following are all the same path, so your solution may not work as anticipated. (I don't know if File::Spec is any better.)

    • c:\Program Files\perl
    • c:\Program Files\Perl
    • c:/Program Files/perl
    • c:\Program Files\\perl
    • c:\progra~1\perl
    • c:\progra~1\java\..\perl
    • .\perl (potentional not the same)
    • c:perl (potentional not the same)