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.
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;
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;
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.
你需要添加\\Q
:
$filename =~s{\Q$i}{$o};
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. 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!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.