perl分裂有趣的行为

时间:2013-09-30 12:37:01

标签: perl split

有人可以解释这种奇怪的行为:

我在一个字符串中有hava路径,我想为每个反斜杠分割它

my $path = "D:\Folder\AnotherFolder\file.txt";

my @folders = split('\', $path);

在上面的情况下,即使转义反斜杠也无法工作:

my @folders = split('\\', $path);

但是在正则表达式的情况下它将起作用:

my @folders = split( /\\/, $path);

为什么会这样?

4 个答案:

答案 0 :(得分:5)

我认为amon在他的评论中给出了你问题的最佳字面答案:

  

更明确:字符串和正则表达式具有不同的转义规则。如果使用字符串代替正则表达式,则字符串文字会遭受双重转义

意味着split '\\'使用字符串而split /\\/使用正则表达式。

作为一个实际的答案,我想补充一点:

也许您应该考虑使用适合拆分路径的模块。 File::Spec是Perl 5中的核心模块。而且,你必须在双引号字符串中转义反斜杠,你还没有这样做。你也可以使用单引号,在我看来看起来好一些。

use strict;
use warnings;
use Data::Dumper;
use File::Spec;

my $path = 'D:\Folder\AnotherFolder\file.txt';  # note the single quotes
my @elements = File::Spec->splitdir($path);
print Dumper \@elements;

<强>输出:

$VAR1 = [
          'D:',
          'Folder',
          'AnotherFolder',
          'file.txt'
        ];

答案 1 :(得分:2)

如果您通过运行来查看文档:

perldoc -f split

您将看到split可以采用的三种形式的参数:

split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/

这意味着即使您将split字符串作为第一个参数传递,perl也会将其强制转换为正则表达式。

如果我们查看在re.pl尝试执行此类操作时收到的警告:

$ my $string_with_backslashes = "Hello\\there\\friend";
Hello\there\friend
$ my @arry = split('\\', $string_with_backslashes);
Compile error: Trailing \ in regex m/\/ at (eval 287) line 6.

我们首先看到,'\\'被内插为反斜杠转义,后跟一个实际的反斜杠,后者计算为单个反斜杠。

split然后把我们给它的反斜杠,并强制它到正则表达式,好像我们写了:

$ my @arry = split(/\/, $string_with_backslashes);

不起作用,因为只有一个反斜杠被解释为简单地转义后面的正斜杠(没有终止/)来表明正则表达式已经结束。

答案 2 :(得分:2)

提取路径元素的一种更简洁的方法是提取以外的所有字符序列路径分隔符。

use strict;
use warnings;

my $path = 'D:\Folder\AnotherFolder\file.txt';
my @path = $path =~ m([^/\\]+)g;

print "$_\n" for @path;

<强>输出

D:
Folder
AnotherFolder
file.txt

答案 3 :(得分:2)

split而非split STRING的形式使用split REGEX时,字符串将转换为正则表达式。在您的情况下,split '\\'将转换为split /\/,因为第一个反斜杠被视为转义字符。

正确的方法是split '\\\\',它将被翻译为split /\\/