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

There has got to be an easier way in perl to get a certain number of words from a line in a string than my code below. Could anyone quickly help me out?

Thanks,

js.

$_="2003-12-20 22:13:58 11 12.37.2.215 407 TCP_DENIED 4294968543 93 GE +T http ping.180solutions.com http://ping.180solutions.com/ - N ONE - -"; @F=split(/\s+/); foreach $i (0 .. 10){ $front.="$F[$i] "; } foreach $i (11 .. 15){ $back.="$F[$i] "; } print "\nFRONT=$front"; print "\nBACK=$back";

20040615 Edit by Corion: Changed title from 'subword'

Replies are listed 'Best First'.
Re: get a certain number of words from a line
by Tomte (Priest) on Jun 15, 2004 at 13:48 UTC

    array-slices are simpler and easier to read:

    $front = join (' ', @F[0..10]); $back = join (' ', @F[11..15]);
    hth

    regards,
    tomte


    An intellectual is someone whose mind watches itself.
    -- Albert Camus

      Or,
      $front = "@F[0..10]"; $back = "@F[11..15]";

      --
      [ e d @ h a l l e y . c c ]

      Bless you tomte!

      Thanks,

      js1.

Re: get a certain number of words from a line
by Roy Johnson (Monsignor) on Jun 15, 2004 at 14:27 UTC
    my ($front, $back) = /((?:\S+\s+){11})((?:\S+\s+){5})/;
    ought to work. I don't have perl5 where I am to test it.

    We're not really tightening our belts, it just feels that way because we're getting fatter.
Re: get a certain number of words from a line
by sleepingsquirrel (Chaplain) on Jun 15, 2004 at 17:59 UTC
    $_=$l="how now brown cow hay is for horses oats are for goats mary lit +tle lamb"; #maybe a little inefficient, but no temp variables, all one line ($f,$b)=(join('',(split)[0..10]), join('',(split)[11..15])); #is there a better way to compose functions? golfers? ($f,$b)=map {join('',(split(/\s+/,$l))[@$_])}([0..10],[11..15]);
    Update: Changed the 2nd snippet above so it doesn't depend on an obscure bug in 5.8.0. For the record you should use array references instead of list refs.
      You seem to be under the impression that
      \(0..10)
      is the same as
      [0..10]
      Update: It appears that they are the same for this particular case, which is (IMO) a Bad Idea, since the \() construct is already a not-uncommon source of confusion. Why was it considered important to make \(something) behave like [something] iff something is a range?

      We're not really tightening our belts, it just feels that way because we're getting fatter.
        I'm under the impression that \(0..10) is a reference to an 11 item list (0,1,2,3,4,5,6,7,8,9,10). And further more, I'm under the impression that...
        $ref=\(1..10); @a[@$ref];
        ...is an eleven item array slide of @a, which happens to be equivalent to @a[0..10]. Try it, you might like it ;)