Reputation: 1151
I try to replace directory part of file fullname in Perl. Something like: got filename 'D:\Texts1\text1' in directory 'D:\Texts1', want to replace it with 'D:\Texts2' and then filename will be 'D:\Texts2\text1'.
I try this code:
$filename = 'D:\Texts1\text1';
$i = 'D:\Texts1';
$o = 'D:\Texts2';
$filename =~ s'$i'$o'g;
And it does not take effect. $filename doesn't changes. I tried to use something like
$i = quotemeta('D:\Texts1');
but it also has not took effect.
Upvotes: 1
Views: 2825
Reputation: 6771
There are several valid answers here, I would like to compile a comprehensive answer along with mine to make this post easier to read:
$i = 'D:\Texts1';
when used as a regex pattern, "\" should be escaped - what the regex engine want is some ultimate format like: D:\\Texts1. So this doesn't work, however, there are at least 4 different ways to build this format as listed below.
Also to notice, when ' is used as delimiter for match or substitution statement, variable interpolation will be disabled, which renders $filename =~ s'$i'$o'g; almost useless. so first step, change it to use / or {}
use quotemeta, this will effectively escape the "\":
$filename = 'D:\Texts1\text1';
$i = quotemeta('D:\Texts1');
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;
use \Q .. \E, which has similar effects as quotemeta:
$filename = 'D:\Texts1\text1';
$i = 'D:\Texts1';
$o = 'D:\Texts2';
$filename =~ s/\Q$i\E/$o/g; # or s/\Q$i/$o/g also works
escape the "\" in the string explicitly, and use qr to quote the string as regex pattern.
$filename = 'D:\Texts1\text1';
$i = qr 'D:\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;
escape to the extent that the string is ready for regex:
$filename = 'D:\Texts1\text1';
$i = 'D:\\\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;
Upvotes: 2
Reputation: 1615
this doesn't interpolate
$filename =~ s'$i'$o'g;
try using /
instead of '
, like this:
$filename =~ s/$i/$o/g;
that should work. '
prevents string interpolation, so the variable names appear as string literals. Also, make sure to use the quotemeta
like you were doing before.
Upvotes: 1
Reputation: 6566
In fact you are experiencing a combination of two problems:
$i
(if you have warnings enabled, you get a clue to this--it tells you that the variables $i and $o are only used once in your program).\Q...\E
construct or quotemeta()
in order to avoid interpreting the special characters in your variable as regexp operators.Upvotes: 0
Reputation: 78
Updated code
use strict;
use warnings qw/all/;
my $filename = 'D:\Texts1\text1';
my $i = 'D:\\Texts1';
my $o = 'D:\\Texts2';
$filename =~ s/\Q$i\E/$o/;
print $filename;
Be happy!
Upvotes: -1
Reputation: 74202
The \
in D:\Texts1
is the problem. You need to escape this metacharacter. For this purpose, the string should be wrapped by \Q
and \E
.
$filename =~ s/\Q$i\E/$o/g;
Upvotes: 1