2013-04-11 39 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