通过正则表达式替换部分文件路径

时间:2012-08-17 14:14:34

标签: regex perl path

我尝试在Perl中替换文件fullname的目录部分。 就像是: 在目录'D:\ Texts1'中得到文件名'D:\ Texts1 \ text1',想要用'D:\ Texts2'替换它,然后文件名将是'D:\ Texts2 \ text1'。

我试试这段代码:

$filename = 'D:\Texts1\text1';
$i = 'D:\Texts1';
$o = 'D:\Texts2';
$filename =~ s'$i'$o'g;

它没有生效。 $ filename不会改变。 我尝试使用像

这样的东西
$i = quotemeta('D:\Texts1');

但它也没有生效。

6 个答案:

答案 0 :(得分:2)

这里有几个有效的答案,我想与我一起编写一个全面的答案,以使这篇文章更容易阅读:

根本原因

$i = 'D:\Texts1';

当用作正则表达式模式时,“\”应该被转义 - 正则表达式引擎想要的是一些最终格式,如: D:\\ Texts1 。所以这不起作用,但是,至少有4种不同的方法来构建这种格式,如下所示。

另外要注意,当'用作匹配或替换语句的分隔符时,将禁用变量插值,这将呈现 $ filename =〜s'$ i'$ o'g; 几乎无用。所以第一步,将其更改为使用/或{}

解决方案1 ​​

使用quotemeta,这将有效地逃避“\”:

$filename = 'D:\Texts1\text1';
$i = quotemeta('D:\Texts1');
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;

解决方案2

使用\ Q .. \ E,其效果与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

解决方案3

显式转义字符串中的“\”,并使用qr引用字符串作为正则表达式。

$filename = 'D:\Texts1\text1';
$i = qr 'D:\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;

解决方案4

转义到字符串为regex准备好的程度:

$filename = 'D:\Texts1\text1';
$i = 'D:\\\\Texts1';
$o = 'D:\Texts2';
$filename =~ s/$i/$o/g;

答案 1 :(得分:1)

\中的D:\Texts1是问题所在。你需要逃避这个元字符。为此,字符串应由\Q\E包裹。

$filename =~ s/\Q$i\E/$o/g;

答案 2 :(得分:1)

这不插入

$filename =~ s'$i'$o'g;

尝试使用/代替',如下所示:

$filename =~ s/$i/$o/g;

应该有用。 '阻止字符串插值,因此变量名称显示为字符串文字。另外,请务必像以前一样使用quotemeta

答案 3 :(得分:0)

您需要添加\Q

$filename =~s{\Q$i}{$o};

答案 4 :(得分:0)

事实上,您遇到了两个问题的组合:

  • 单引号虽然作为正则表达式分隔符有效,但具有特殊含义:它们禁用变量插值。因此,您正在搜索字符串中的文字模式$i(如果您启用了警告,则会得到一个线索 - 它告诉您变量$ i和$ o仅在您的程序中使用一次)。
  • 正如其他人指出的那样,您还需要\Q...\E构造或quotemeta(),以避免将变量中的特殊字符解释为regexp运算符。

答案 5 :(得分:-1)

更新了代码

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;

快乐!

相关问题