2013-04-11 131 views
0

我最初是由這個疑惑:我只是努力在Perl,字符分割功能時,我注意到了這一點:從Perl中分割過濾數組中的空字符串?

DB<56> map(print("-", $_, "\n"), split(//, "test") ); 
-t 
-e 
-s 
-t 

    DB<57> map(print("-", $_, "\n"), split(/./, "test") ); 

    DB<58> map(print("-", $_, "\n"), split(/(.)/, "test") ); 
- 
-t 
- 
-e 
- 
-s 
- 
-t 

我已經知道了if the empty regex // is used, the string is split into individual characters;但我不清楚/(.)/正則表達式中的那些空字符串來自哪裏 - 但只是幾句話後,頁面指出「如果正則表達式有分組,那麼生成的列表包含來自分組的匹配子字符串...因爲$ x的第一個字符與正則表達式匹配,所以split將一個空的初始元素添加到列表中。「所以,這是預期的行爲。 (althgouh,我仍然不清楚爲什麼取消分組/./不會做任何事情)

但是,我也在Python工作,並遇到類似的問題(在分裂的結果空字符串) - 我在那裏發現一個filter(None, list)函數,在此調用中,該函數只是從列表中刪除空字符串。在Perl中使用什麼來實現相同的功能?

+2

你會看到一個更好的畫面,如果你通過'-1'爲'split'的第三個參數。 – ikegami 2013-04-11 15:26:34

+3

使用'map'作爲foreach循環令人不悅。除了小的低效率之外,它向讀者承諾一件事,但另一件事承諾。 ('print' - $ _ \ n「分割...;') – ikegami 2013-04-11 15:27:42

回答

5

split的第一個參數定義了什麼分離您正在解析的列表的術語。在最後兩個片段中,您告訴split任何字符都是有效的分隔符,因此split返回輸入字符之間的內容:五個空字符串。

>perl -E"say qq{<$_>} for split /./, 'test', -1;" 
<> 
<> 
<> 
<> 
<> 

(尾隨空字符串默認過濾掉。)

的解決方法是不啓動過濾掉你問split產生非常的事。無論哪種解決您的分離

my @chars = split /(?<=.)|(?=.)/s; 
my @chars = split //; 

或使用更好的工具

my @chars = /(.)/s; 
my @chars = unpack '(a)*', $_; 
+0

非常感謝那個@ikegami - 對於遲到的接受感到抱歉;然而,如果原則上(用不同的正則表達式)我得到一個數組,我想過濾空字符串,現在我會這樣做(像Python的'filter(None,list)')?我聽說過@arr = grep {defined} @arr;'應該可以工作,但我只是試過了,它仍然留下空字符串...... – sdaau 2014-07-16 02:56:58

+0

啊,通過[如何忽略perl中的任何空值grep?](http://stackoverflow.com/questions/6631043/how-to-ignore-any-empty-values-in-a-perl-grep/6631252#6631252):它應該是'@arr = grep {不是/^\ s * $ /} @arr;' - 過濾掉空字符串。乾杯! – sdaau 2014-07-16 03:02:23

+0

'grep {!length} @ arr' – ikegami 2014-07-16 03:16:05