Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Split at specific spaces

by perl_search_m (Novice)
on May 11, 2010 at 07:08 UTC ( [id://839380]=perlquestion: print w/replies, xml ) Need Help??

perl_search_m has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I want to perform a split on the following line:
1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15
where I want the program to split at every third space occurence.. The output of above line should like this:
1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15
Is there any way I can perform the above? Kindly guide me

Replies are listed 'Best First'.
Re: Split at specific spaces
by BrowserUk (Patriarch) on May 11, 2010 at 07:13 UTC
    Is there any way I can perform the above?

    Not particularly efficient, but possible:

    $s = '1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15';; print for grep length, split /(\S+\s+\S+\s+\S+)\s+/, $s;; 1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Split at specific spaces
by rubasov (Friar) on May 11, 2010 at 08:15 UTC
    Another way returning the split parts only:
    perl -E 'say for split /\S+\s+\S+\s+\S+\K\s+/, "1 2 3 4 5 6 7 8 9"'
    Or written shorter:
    perl -E 'say for split /(?:\S+\K\s+){3}/, "1 2 3 4 5 6 7 8 9"'
      perl -E 'say for split /\S+\s+\S+\s+\S+\K\s+/, "1 2 3 4 5 6 7 8 9"'

      Neat!++ It never crossed my mind that /K would work with split.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      As a newbie I'm reading and deciphering your response. My reference material doesn't seem to mention "K" anywhere. Can you (or anyone) enlighten me?

Re: Split at specific spaces
by toolic (Bishop) on May 11, 2010 at 13:05 UTC
    Another way is to use List::MoreUtils::natatime
    use strict; use warnings; use List::MoreUtils qw(natatime); my $line = '1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15'; my @tokens = split /\s+/, $line; my $it = natatime(3, @tokens); while (my @vals = $it->()) { print "@vals\n"; }
Re: Split at specific spaces
by johngg (Canon) on May 11, 2010 at 12:08 UTC

    Another way just using a global match with an alternation of look-behinds rather than split.

    $ perl -E ' $_ = q{1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15}; say for m{(?: (?<=\A) | (?<=\s) )( (?:\S+\s+){2} \S+ ) }gx;' 1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15 $

    I hope this is useful.

    Cheers,

    JohnGG

Re: Split at specific spaces
by Cristoforo (Curate) on May 11, 2010 at 16:28 UTC
    #!/usr/bin/perl use strict; use warnings; $_ = '1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15'; print join "\n", /\S+(?: \S+){1,2}/g;
    Update: above solution better as:

    print "$1\n" while /(\S+(?:\s+\S+){0,2})/g;

Re: Split at specific spaces
by johngg (Canon) on May 11, 2010 at 23:05 UTC

    Yet another way using split on spaces but with a capture so the spaces are retained. Discard every 6th element then join five at a time.

    $ perl -E ' > $_ = q{1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15}; > @e = grep { ( ++ $i ) % 6 } split m{(\s+)}; > say join q{}, map { shift @e } 1 .. 5 while @e;' 1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15 $

    Cheers,

    JohnGG

      And Another One Way

      $name=qq(1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15); split (/ /, $name); ### Process the temp array for ( $i=0; $i<=$#_; $i++) { push @get, (join ' ', @_[$i..$i+2]); $i=$i+2; } print "\n$_" for @get;
        While this code does produce correct results in this case, you are ignoring a warning message because you do not use strict and warnings:
        Use of implicit split to @_ is deprecated
Re: Split at specific spaces
by Anonymous Monk on May 13, 2010 at 11:58 UTC
    doesn't seem that difficult.
    $ perl -le 'use strict;use warnings;my($s,@r,@t) = "1 AC2 34 TRP A 6 A +LA A 7 ILE A 14 GLY A 15";@t=split/\s+/,$s;while((@r=splice @t,0,3)== +3){print join(" ",@r);}warn"leftovers: @r\n"if @r;' 1 AC2 34 TRP A 6 ALA A 7 ILE A 14 GLY A 15
    what's the catch?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://839380]
Approved by moritz
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-24 21:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found