Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

split split

by Plankton (Vicar)
on Jun 23, 2009 at 15:59 UTC ( #774078=perlquestion: print w/replies, xml ) Need Help??
Plankton has asked for the wisdom of the Perl Monks concerning the following question:

I know there has to be a nicer way to write this ...
while ( <FH> ) { my ( $part1, $junk ) = split /#/; my ( $junk2, $ipaddr ) = split / /, $part1;
the input line might look like ...
client query: IN AAAA +
... The thing I can't figure out is how to access the result of split as an array without having to declare and assign it to a variable. You know ...
print @(split /#/)[1];
... something like that right?

Replies are listed 'Best First'.
Re: split split
by sundialsvc4 (Abbot) on Jun 23, 2009 at 16:10 UTC

    (Shrug...) What you've got now is clear and it works. What's not to luv?

    Please give me code that is “clear,” any day, over code that is “clever.” I can look at your example and instantly comprehend how it works. I can also tweak it without too much fear of breaking it. That, to me, is a very compelling argument in favor of what you started with.

Re: split split
by davorg (Chancellor) on Jun 23, 2009 at 16:03 UTC
Re: split split
by suaveant (Parson) on Jun 23, 2009 at 16:17 UTC
    Split is usually used for breaking up a string, for pulling a specific piece of a string out usually a regexp is a better bet

    if($string = /^client\s+(\d+\.\d+\.\d+\.\d+)/) { $ipaddr = $1; } else { die 'horribly'; }

                    - Ant
                    - Some of my best work - (1 2 3)

Re: split split
by oko1 (Deacon) on Jun 23, 2009 at 16:21 UTC

    You can specify multiple delimiters for 'split':

    while (<FH>){ print +(split /#|\s/)[1]; }

    "Language shapes the way we think, and determines what we can think about."
    -- B. L. Whorf
Re: split split
by artist (Parson) on Jun 23, 2009 at 21:56 UTC
    If you really need the 'ip address', you can use the right expression.
    use Regexp::Common qw/net/; + my $ip_regexp = qr($RE{net {IPv4}); + while(<DATA>) { + if (/($ip_regexp)/) { + my $ip_address = $1; + print "$ip_address\n"; + } + } + + __DATA__ + client query: IN AAAA +
Re: split split
by moritz (Cardinal) on Jun 23, 2009 at 16:05 UTC
    $ perl -wle 'print +(split /#/, "a#b")[1];' b

    You can also use undef where you don't want variable names:

    my (undef, $a) = split ...
Re: split split
by toolic (Bishop) on Jun 23, 2009 at 16:12 UTC
    You can split split, but it may not be the best solution:
    use strict; use warnings; while (<DATA>) { my $ipaddr = (split /\s+/, (split /#/, $_)[0])[1]; print "ipaddr = $ipaddr\n"; } __DATA__ client query: IN AAAA +


    ipaddr =
Re: split split
by Marshall (Abbot) on Jun 23, 2009 at 17:36 UTC
    You are very close and I don't see anything wrong with this approach.

    The first split is in a list context and there is no need to assign "junk". The 2nd split should also be put into a list context and then just take the 2nd thing via a "list slice", [1] subscript. See below..

    #!/usr/bin/perl -w use strict; my $line = 'client query: IN AAAA'; my ( $part1) = split (/#/,$line); my ( $ipaddr ) = (split(/\s+/, $part1))[1]; print " part1: $part1\n ipaddr: $ipaddr\n"; __END__ Prints: part1: client ipaddr:
    Occasionally you will see:
    (undef, my $ipaddr) = split(/\s+/, $part1);
    And although that will work, I wouldn't use it. Assigning something to undef as a lvalue "throws it in the bit bucket". I think it is "cleaner" to use the slice.

    Update: Now of course, if you just want the IP address:

    my $line = 'client query: IN AAAA'; (my $ipaddr) = (split/[\s#]/,$line)[1]; print "$ipaddr\n"; __END__ prints:
Re: split split
by FunkyMonk (Canon) on Jun 23, 2009 at 19:05 UTC
    And another way...

    You want the stuff between the first space and the first hash

    $_ = "client query: IN AAAA +"; (my $ip) = /\s(.*?)#/; print $ip; #

    Unless I state otherwise, all my code runs with strict and warnings
Re: split split
by linuxer (Curate) on Jun 23, 2009 at 17:42 UTC

    If you are sure about the format of your input data (order of fields, number of whitespaces, ...), you can try something like this:

    my $line = 'client query: IN AAAA +' +; my ( $ip, $host ) = ( split /[ #]/, $line, 6 )[1,4]; print "IP: $ip, HOST: $host\n";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://774078]
Approved by toolic
[shmem]: thanks vrk - but I'll rather have a plate of "silly con charme"
Lady_Aleena is trying to explain perl regexen to people right now and explaining how variables expand in regexen.
[Lady_Aleena]: The people I'm talking with think /$var/ looks weird with some saying it shouldn't work.

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2017-04-28 09:45 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (520 votes). Check out past polls.