get a certain number of words from a line
js1
created: 2004-06-15 09:40:16

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 GET 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'

Re: get a certain number of words from a line
created: 2004-06-15 09:48:40

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

Re^2: get a certain number of words from a line
js1
created: 2004-06-15 09:52:16

Bless you tomte!

Thanks,

js1.

Re^2: get a certain number of words from a line
created: 2004-06-15 10:08:24
Or,
$front = "@F[0..10]";
$back = "@F[11..15]";

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

Re: get a certain number of words from a line
created: 2004-06-15 10:27:53
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
created: 2004-06-15 13:59:57
$_=$l="how now brown cow hay is for horses oats are for goats mary little 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.
Re^2: get a certain number of words from a line
created: 2004-06-15 14:10:15
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.
Re^3: get a certain number of words from a line
created: 2004-06-15 14:26:36
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 ;)
Re^4: get a certain number of words from a line
created: 2004-06-15 15:10:51
I'd like to try it, but I don't have perl5 where I am this week. My understanding is that \(1..10) is shorthand for (\1,\2,\3,...,\10), and that your list will be flattened, so that (\(1..10),\(11..15)) is the same as \(1..15).

It's not a feature I've used, myself, so I could certainly be misunderstanding it. If I am, I would genuinely appreciate someone making it clear to me.

It took me a minute to decode "array slide" as "array slice". I thought you were talking about a feature I'd never heard of!

Update: from perlref:

Taking a reference to an enumerated list is not the same as using square brackets--instead it's the same as creating a list of references! 

We're not really tightening our belts, it just feels that way because we're getting fatter.
Re^5: get a certain number of words from a line
created: 2004-06-15 16:02:18
Hmmm... Apparently not for my perl...
greg@sparky:~/test$ cat ./list_ref 
#!/usr/bin/perl -w

@a=qw/zero one two three four five/;
$ref=\(1..3);
@b=@a[@$ref];

print "\n \@a=@a\n \$ref=$ref\n \@b=@b\n\n";

greg@sparky:~/test$ ./list_ref 

 @a=zero one two three four five
 $ref=ARRAY(0x813dcc0)
 @b=one two three

greg@sparky:~/test$ perl -v

This is perl, v5.8.0 built for i486-linux

Copyright 1987-2002, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit. 

...And sorry for the typo. This thread (among others) has finally inspired me to create my first perlmonks .sig.


-- All code is 100% tested and functional unless otherwise noted.
Re^5: get a certain number of words from a line
created: 2004-06-15 16:39:05
"Enumerated list" must be the key concept.
greg@sparky:~/test$ cat enum 
#!/usr/bin/perl -w
use Data::Dumper;

$ref=\(0..3);
$enum_list=\(4,5,6);

print "\n".Dumper($ref)."\n";
print "\n".Dumper($enum_list)."\n";

greg@sparky:~/test$ ./enum 

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


$VAR1 = \6;


-- All code is 100% tested and functional unless otherwise noted.
Re^6: get a certain number of words from a line
created: 2004-06-15 17:29:44
What do you get if you do
$x = \((0..3));
?

As a general rule, I would recommend use of [0..10] instead of the capricious \(0..10), since the former is always a way to get an array ref (and is a char shorter), while the latter is usually a way to make a list of references.


We're not really tightening our belts, it just feels that way because we're getting fatter.
Re^7: get a certain number of words from a line
created: 2004-06-15 21:31:35
Must have been a bug in 5.8.0 that was causing the behavior. Upgrading to 5.8.4 makes it behave like everyone expects. Just for the record, here's what you get for the above query on 5.8.0...
perl -e '$x = \((0..3)); print @$x'
0123


-- All code is 100% tested and functional unless otherwise noted.

perlmonks.org content © perlmonks.org and halley, js1, Roy Johnson, sleepingsquirrel, Tomte

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03