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

如何在Perl中规范化Windows文件路径?,windows,perl,filepath,backslash,Windows,Perl,Filepath,Backslash,更新: 我可以使这成为一个更简单的问题来解决: 我想找出正确的正则表达式是什么,用两个反斜杠替换任何一个反斜杠 我想把这个转变为: vlc.plugin.path = C:\Program Files\JekyllV0.9.2\\VLC_1.0.0\\plugins 进入: 原始问题: 我想使用Perl正则表达式更改文件中的以下内容: 一个反斜杠到两个反斜杠的所有引用 一个正斜杠到两个反斜杠的所有引用 我尝试了以下方法: perl" -p -i.orig -e "s#\\#\\\\#g"

更新:

我可以使这成为一个更简单的问题来解决:

我想找出正确的正则表达式是什么,用两个反斜杠替换任何一个反斜杠

我想把这个转变为:

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

原始问题:

我想使用Perl正则表达式更改文件中的以下内容:

  • 一个反斜杠到两个反斜杠的所有引用
  • 一个正斜杠到两个反斜杠的所有引用
我尝试了以下方法:

perl" -p -i.orig -e "s#\\#\\\\#g" -e "s#/#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%
其中%VIDEOLOG\u属性\u文件%包含:

vlc.plugin.path = C:\Program Files\JekyllV0.9.2/VLC_1.0.0/plugins
对于基本替换:

perl -p -i.orig -e "s#[/\\]#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%
要仅替换与同一字符的另一个实例不相邻的斜杠和反斜杠,请执行以下操作:

perl -p -i.orig -e "s#(?<!/)/(?!/)#\\\\#g; s#(?<\\)\\(?!\\)#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%
perl-p-i.orig-e“s#”(?用于基本替换:

perl -p -i.orig -e "s#[/\\]#\\\\#g" %VIDEOLOG_PROPERTIES_FILE%
要仅替换与同一字符的另一个实例不相邻的斜杠和反斜杠,请执行以下操作:

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

perl-p-i.orig-e“s#(?我很确定perl会盲目地连接它的所有
-e
参数,所以这些参数被压缩成
s#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

如果我将其更改为
-e's\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


当然,你可以用一个正则表达式来实现这一点,因为你两次都使用相同的替换项。

我敢肯定Perl会盲目地连接它所有的
-e
参数,所以这些参数会被压缩成
s\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

[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
如果我将其更改为
-e's\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


当然,您可以用一个正则表达式来实现这一点,因为您两次都使用相同的替换项。

它不起作用,因为perl不能处理两个
-e
标志——在两个命令之间没有分号。您必须按如下方式编写它(如果您在“perl”后面丢失了d引号)

[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
我做了类似的事情,但是因为Perl在PC上支持
“/”
,所以我更喜欢使用正向斜杠

s![\\/]+!/!g;
因此,它可以很容易地转为

s![\\/]+!\\\\!g;
现在说说我为什么这么做:有时候人们不知道他们是否应该在要连接的路径的开始或结束部分放一个斜杠。有时你甚至会得到两个正斜杠。(但如果你使用。)因此,处理这些类型的碰撞是很好的,特别是因为这将是一条路径,我们想用任意多的斜线,把它们变成我们喜欢的类型

此外,我甚至会这样做:

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

因为它捕获的是由一个点分隔的同一个斜杠簇,而这个点不起任何作用,因为路径方面的
/
(/+)+
对于那些处理路径名中的点的程序和脚本,而其他程序将出错。

这不起作用,因为perl不处理两个
-e
标志——在两个命令之间没有分号。您必须按以下方式编写它(如果您在“perl”后面丢失了d-quote,也就是说)

我做了类似的事情,但是因为Perl在PC上支持
“/”
,所以我更喜欢使用正向斜杠

s![\\/]+!/!g;
因此,它可以很容易地转为

s![\\/]+!\\\\!g;
现在说说我为什么这么做:有时候人们不知道他们是否应该在要连接的路径的开始或结束部分放一个斜杠。有时你甚至会得到两个正斜杠。(但如果你使用。)因此,处理这些类型的碰撞是很好的,特别是因为这将是一条路径,我们想用任意多的斜线,把它们变成我们喜欢的类型

此外,我甚至会这样做:

s!([\\/]+([.][\\/]+)?)+!/!g
因为它捕获的是由一个点分隔的同一组斜杠,而这个点不起任何作用,因为路径方面的
/
(/+)++
用于处理路径名中的点的程序和脚本,而其他程序将出错。

您需要

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

#!/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 C:\\Program Files\\JekyllV0.9.2\\VLC\U 1.0.0\\plugins C:\\Program Files\\JekyllV0.9.2\\VLC\U 1.0.0\\plugins 你想要的

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

#!/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 C:\\Program Files\\JekyllV0.9.2\\VLC\U 1.0.0\\plugins C:\\Program Files\\JekyllV0.9.2\\VLC\U 1.0.0\\plugins
不知道MSWindows是如何处理这些事情的,但你可能想再次尝试摆脱所有的反斜杠。是的,Perl就是这么做的。(只是开玩笑,我喜欢Perl;-))Perl回答说:语法错误在-e行2,靠近“s”/“g”由于编译错误,-e的执行被中止。不,他实际上把所有的反斜杠都加倍了,即使是对于有两个反斜杠的序列也是如此。@Axeman,不知道你的意思。我想perl会把's\\\\\\\\\\\\\\\\\\\\\\\\\'看作's\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'(无效)在逃避之后,就像在unix shell中一样。看看答案,这似乎不是问题。不确定MSWindows如何处理这些事情,但你可能想尝试再次摆脱所有的反斜杠。是的,Perl就是这么做的。(只是开玩笑,我喜欢Perl;-)Perl的回应是:在-e第2行,靠近“s#/#\\\#g”的位置出现语法错误,由于编译错误,-e的执行被中止。不,他实际上将所有反斜杠加倍,即使是有两个反斜杠的序列。@Axeman,不确定你的意思。我在想perl看到的是#\\#\