ohRlyeh
ohRlyeh

Reputation: 1

Cannot remove Windows directory path containing backslashes using Perl regex

I want to remove the first part of a file's full path using a regex in perl. But it doesn't work when backslashes are used in the paths. Consider test.pl below

$fileName = 'C:\someDirectory\anotherDirectory\someFile.txt';
$dirName  = 'C:\someDirectory';

print "$fileName\n";

$fileName =~ s/$dirName//;

print "$fileName\n";


$fileName = 'C:#someDirectory#anotherDirectory#someFile.txt';
$dirName  = 'C:#someDirectory';

print "$fileName\n";

$fileName =~ s/$dirName//;

print "$fileName\n";

Output looks like this:

C:\someDirectory\anotherDirectory\someFile.txt
C:\someDirectory\anotherDirectory\someFile.txt
C:#someDirectory#anotherDirectory#someFile.txt
#anotherDirectory#someFile.txt

Why doesn't the substitution work when backslashes are in the string? How can I get around this?

Upvotes: 0

Views: 365

Answers (1)

Miller
Miller

Reputation: 35198

Literal Strings in a Regex

A backslash is a regex special character, therefore it must be escaped if it's intended as part of a literal string within the regex.

To do that, you can simply use quotemeta or the \Q...\E escape sequence:

my $fileName = 'C:\someDirectory\anotherDirectory\someFile.txt';
my $dirName  = 'C:\someDirectory';

print "$fileName\n";

$fileName =~ s/\Q$dirName\E//;

print "$fileName\n";

Outputs:

C:\someDirectory\anotherDirectory\someFile.txt
\anotherDirectory\someFile.txt

Path::Class for File & Dir Manipulation

Alternatively, you can use a module like Path::Class for cross platform compatible file and directory manipulation.

The following is your same goal executed thusly:

use Path::Class;

my $file = file('C:\someDirectory\anotherDirectory\someFile.txt');
my $dir  = dir('C:\someDirectory');

my $rel = $file->relative($dir);

print "$rel\n";

Outputs:

anotherDirectory\someFile.txt

Upvotes: 1

Related Questions