2012-08-25 67 views
4

我通過兩種方法使用分割功能。第一種方式:使用Perl分割點使用

my $string="chr1.txt"; 
my @array1=split(".",$string); 
print $array1[0]; 

我得到這個錯誤:Use of uninitialized value in print

當我做第二路分離的,我沒有任何錯誤。

my @array1=split(/\./,$string);print $array1[0]; 

我的第一種拆分方式不適用於點。

有人能解釋一下這個背後的原因嗎?

+0

split(「。」)or split(/\./) – gaussblurinc

+5

@loldop這是錯誤的答案,因爲'split'的參數總是被解釋爲一個模式。傳遞''。「'的參數與傳遞'/./'參數相同:*** *** ***分割爲非換行符'[^ \ n]'或'\ N' - ***除非使用''re'/ m「'作爲範圍,在這種情況下,它會在任何一個Perl代碼點上分割,包括高於0x1F_FFFF的非Unicode代碼點。 – tchrist

回答

6

,如果你只是想解析文件,並得到他們的後綴,更好地運用fileparse()方法從File::Basename

+1

'fileparse'並不是這個問題的一個改進的解決方案,因爲它所做的只是提供一種更尷尬的方式來應用正則表達式。如果後綴總是以點開始,那麼基名應該使用'my($ name,$ suffix)= $ filename =〜/(.*)(\..*)/' – Borodin

9

"\."只是.,小心轉義序列。

如果你想在雙引號字符串中使用反斜槓和點,你需要"\\."。或者使用單引號:'\.'

+1

分割。確實如此。順便說一句,模式中的命名字符不受元字符解釋的限制。也就是說,'split/\ N {FULL STOP} /'將是一個文字。這與使用像'split'\ N {FULL STOP}這樣的字符串截然不同,它只是元字符**,因爲模式引擎從來沒有看到它是*語法上的*一個有名字符**比較' perl5.16.0 -lE'表示分割/ \ N {FULL STOP} /,「foo.bar.glarch」'與'perl5.16.0 -lE'表示分割「\ N {FULL STOP}」,「 foo.bar.glarch「」看我的意思。 – tchrist

3

其他細節由@Mat提供的信息:

split "\.", ...split第一個參數傳遞給正則表達式引擎之前首先解釋爲一個雙引號字符串。正如Mat在雙引號字符串中所說的那樣,\是轉義字符,意思是「逐字地取下一個字符」,例如例如在雙引號字符串內放雙引號之類的東西:"\""

所以你的split通過"."作爲模式。單個點意味着「分割任何角色」。如你所知,分割模式本身不是結果的一部分。所以你有幾個空字符串作爲結果。

但爲什麼第一個元素未定義而不是空的?答案在於split的文檔:如果您沒有對split(其第三個參數)返回的元素數量施加限制,那麼它將默默刪除列表末尾的空結果。由於所有項目均爲空,因此列表爲空,因此第一個元素不存在且未定義。

你可以看到這個特定摘錄的區別:

my @p1 = split "\.", "thing"; 
my @p2 = split "\.", "thing", -1; 
print scalar(@p1), ' ', scalar(@p2), "\n"; 

它輸出0 6

然而,「適當」的方式來解決這個問題是@ soulSurfer2010在他的文章中所說的。