如何在Perl中规范化Windows文件路径?

时间:2009-08-20 18:56:43

标签: windows perl filepath backslash

更新

我可以解决这个问题更简单的问题:

我想弄清楚正确的正则表达式是用两个反斜杠替换任何一次反斜杠的情况。

我想转此:

vlc.plugin.path = C:\Program Files\JekyllV0.9.2\\VLC_1.0.0\\plugins

成:

vlc.plugin.path = C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins

原始问题:

我想使用Perl Regex在文件中更改以下内容:

  • 所有出现的单个反斜杠到两个反斜杠
  • 所有出现的单个正斜杠到两个反斜杠

我尝试了以下内容:

perl" -p -i.orig -e "s#\\#\\\\#g" -e "s#/#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%

%VIDEOLOG_PROPERTIES_FILE%包含:

vlc.plugin.path = C:\Program Files\JekyllV0.9.2/VLC_1.0.0/plugins

5 个答案:

答案 0 :(得分:6)

基本替换:

perl -p -i.orig -e "s#[/\\]#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%

仅替换与同一字符的另一个实例不相邻的斜杠和反斜杠:

perl -p -i.orig -e "s#(?<!/)/(?!/)#\\\\#g; s#(?<\\)\\(?!\\)#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%

答案 1 :(得分:4)

你想要File::Spec->canonpath

更新:: 实际上,这是错误的建议。这将适用于内部函数调用等,但它会向文件写入单个反斜杠。但是,以下内容会更好:

#!/usr/bin/perl

use strict;
use warnings;

use Config::INI::Reader;

my $config = Config::INI::Reader->read_handle(\*DATA);

my $var1 = $config->{_}->{'vlc.plugin.path1'};
my $var2 = $config->{_}->{'vlc.plugin.path2'};

for my $v ($var1, $var2) {
    $v =~ s! (?: [\\]{1,2} ) | (?:/) !\\\\!gx;
    print "$v\n";
}

__DATA__
vlc.plugin.path1 = C:\Program Files\JekyllV0.9.2\\VLC_1.0.0\\plugins
vlc.plugin.path2 = C:\Program Files\JekyllV0.9.2/VLC_1.0.0/plugins

输出:

C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins
C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins

答案 2 :(得分:3)

我很确定Perl会盲目地连接所有-e个参数,所以这些参数被压缩到s#\\#\\\\#gs#/#\\\\#g,然后第二个正则表达式就像是一个注释。

如果我将其更改为-e 's#\\#\\\\#g; s#/#\\\\#g',它对我有用。

当然,您可以使用单个正则表达式执行此操作,因为您两次都使用相同的替换。

答案 3 :(得分:3)

它不起作用,因为perl不处理两个-e标志 - 两个命令之间没有分号。您必须按如下所示编写它(如果您在'perl'之后丢失了d-quote,那就是。)

perl -p -i.orig -e "s#\\#\\\\#g;" -e "s#/#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%

我做了类似的事情,但因为Perl在PC上支持'/',我的偏好是正斜杠。所以我使用以下内容:

s![\\/]+!/!g;

因此可以很容易地转向

s![\\/]+!\\\\!g;

现在谈谈我为什么这样做:有时人们无法弄清楚他们是否应该在将要连接的路径部分的开头或结尾处加上斜线。有时你最终会得到双正斜杠。 (但是如果你使用File::Spec则不行。)因此处理那些类型的碰撞是很好的。特别是因为它将成为一条道路,我们想要采取任何类型的许多斜线并将它们变成我们喜欢的那种。

另外,我甚至这样做:

s!([\\/]+([.][\\/]+)?)+!/!g

因为它捕获那些由一个点分隔的相同的斜线簇而不会起作用的情况,因为路径/&lt; =&gt; (/+.)+用于处理路径名中点的程序和脚本,而其他程序则会出错。

答案 4 :(得分:0)

[21:09:00][mgrad@zuza-3:~]$ perl -pe 's#\/#\/\/#g; s#\\#\\\\#g' test.txt
vlc.plugin.path = C:\\Program Files\\JekyllV0.9.2//VLC_1.0.0//plugins