Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Split at specific spaces

by perl_search_m (Novice)
on May 11, 2010 at 07:08 UTC ( #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

Comment on Split at specific spaces
Select or Download Code
Replies are listed 'Best First'.
Re: Split at specific spaces
by BrowserUk (Pope) 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 (Abbot) 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 (Deacon) 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 (Abbot) 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
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? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2015-07-30 10:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (271 votes), past polls