tab - perl分裂有趣的行為
unix perl split (3)
有人可以解釋這個奇怪的行為:
我有一個字符串的路徑,我想分裂為每個反斜杠
my $path = "D:\Folder\AnotherFolder\file.txt";
my @folders = split('\', $path);
在上面的情況下,即使像這樣轉義反斜杠也不行:
my @folders = split('\\', $path);
但在正則表達式的情況下,它將工作:
my @folders = split( /\\/, $path);
為什麼是這樣?
如果您通過運行查看文檔:
perldoc -f split
你會看到split
可以採取的三種形式的論據:
split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
這意味著,即使當你傳遞一個字符串作為第一個參數, 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);
這是行不通的,因為只有一個反斜杠被解釋為簡單地在正斜杠後面(而不是終止/
)顯示正則表達式已經結束。
我認為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'
];
當以split STRING
的形式使用split STRING
而不是split REGEX
,字符串被轉換成正則表達式。 在你的情況下, split '\\'
將被轉換為split /\/
因為第一個反斜杠被認為是一個轉義字符。
正確的做法是split '\\\\'
,將其轉換為split /\\/
。