Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Remove empty element.

by vinoth.ree (Monsignor)
on Jul 14, 2009 at 05:09 UTC ( #779791=perlquestion: print w/replies, xml ) Need Help??
vinoth.ree has asked for the wisdom of the Perl Monks concerning the following question:

use strict; use warnings; use Data::Dumper; my $test="[1,2,3]"; my @var = split(/[\]\[,]/,"[1,2,3]"); print Dumper \@var;

In the above code I split the string using the separators [], So I got the output in the @var array as follows.

$VAR1 = [ '', '1', '2', '3' ];

As I know that I get the empty element at first because it matches the first character of $var matched the regular expressions. I do not want this empty element in the @var array.

I did the following to avoid the empty element as

use strict; use warnings; use Data::Dumper; my $test="[1,2,3]"; my $empty; my ($empty,@var) = split(/[\]\[,]/,"[1,2,3]"); print Dumper \@var;

Do you have any better idea to avoid the empty element ?


Title modified

Replies are listed 'Best First'.
Re: Remove empty element.
by ikegami (Pope) on Jul 14, 2009 at 05:16 UTC

    Do you have any better idea to avoid the empty element ?

    Yeah, don't use split to parse something that isn't a uniform list.

    At a minimum, you could use the following:

    my @var = $test =~ /\d+/g;

    A little more flexible:

    my ($list) = $test =~ /\[ ( [^\]]* ) \]/x; my @var = split /,/, $list;

    By the way, the following needlessly creates two variables that are never used (and issues a warning for having two variables with the same name):

    my $empty; my ($empty,@var) = ...;

    You want:

    (undef, my @var) = ...;

    Update: Fixed pattern.

Re: Remove empty element.
by jwkrahn (Monsignor) on Jul 14, 2009 at 05:16 UTC

    This should work better:

    my $test="[1,2,3]"; my @var = $test =~ /\d+/g; print Dumper \@var;

      This works fine for numbers only, the element may be any character, In this case what can I do ?

        my $test = "[1,2,3]"; my @var = $test =~ /[^][,]+/g; print Dumper \@var;
        The second example given by ikegami above should work for you , provided you have a defined separator that doesn't conflict with your data.
Re: Remove empty element.
by rovf (Priest) on Jul 14, 2009 at 07:45 UTC
    As I know that I get the empty element at first
    You can unconditionally remove the first element of a list using shift.

    Ronald Fischer <>
      Or grep away null elements. I admit that I do this sometimes simply to save cognitive load as opposed to CPU load.
      my @array = ('',1,2,'',3,'',4); @array = grep { $_ } @array; print join "}{",@array; print "\n";
        @array = grep { $_ } @array;

        This grep also removes array elements that happen to be 0. Use grep { defined && length } instead if you want to have the 0 elements in the result.


        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Winnowing solutions to the best one (was Re: Remove empty element.)
by roboticus (Chancellor) on Jul 14, 2009 at 11:51 UTC


    I see you've got plenty of responses from which to choose. But I thought I'd comment anyway. Since you have a variety of methods now at your fingertips, how do you select the one you should use in your application? By looking them over while paying attention to the stated/unstated assumptions.

    • Capture only the items you want like:
      my @var = $test =~ /\d+/g;
      The important assumption in this solution is that the items you want are strings of digits.
    • Regex capture followed by split
      my ($list) = $test =~ /\[ ( [^\]]+ ) \]/x, $1); my @var = split /,/, $list;
      The assumptions here are: (a) your string always contains an argument list surrounded by &#91; and &#93;.
    • Explicitly ignore the first item in an array assignment
      (undef, my @var) = ...; Assumes you always want to delete the first item in the list. As rofv mentions above, another way to ignore the first item is to just use shift after creating your @var array.
    • I was originally going to suggest you filter out the empty items (via grep). The assumption being that you don't want any empty items anywhere in your list.

    By paying attention to the assumptions your code makes and the assumptions the proposed solutions make, you can select a method with the fewest mismatched assumptions. Note also that assumptions are closely related to constraints--learning to see the assumptions made by code also helps you to recognize constraints in your code. As you recognize them, you can avoid adding gratuitous constraints to your programs.


    Update: Replaced empty NOTES: at end with an Update: block. (I removed the item requiring a note without removing the notes block....)

Re: Remove empty element.
by Bloodnok (Vicar) on Jul 14, 2009 at 13:54 UTC
    Following on from ikegamis suggestion, you could (possibly i.e. if it suits) assert the uniformity of the list by treating all (sequences of) non-alpha numeric chars as delimiters:
    use Data::Dumper; my @els = '[1,2,3]' =~ /(\w+)/g; print Dumper \@els;
    $VAR1 = [ '1', '2', '3' ];
    A user level that continues to overstate my experience :-))

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://779791]
Approved by ikegami
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2017-07-23 05:09 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (344 votes). Check out past polls.