tags:

views:

88

answers:

2

In perl, I have a string that roughly looks like

my $str = "one  10 two   20   three    30";

Now, I'd like to split that string into word-number pairs, but have no success.

I thought I could do a

my @pairs = split /([a-z]+[^a-z]+)/, $str;

and would then have

$pairs[0] eq 'one  10 '
$pairs[1] eq 'two   20   '
$pairs[2] eq 'three    30'

However, I get

$pairs[0] eq ' '
$pairs[1] eq 'one  10 '
$pairs[2] eq ' '
$pairs[3] eq 'two   20   '
$pairs[4] eq ' '
$pairs[5] eq 'three    30'

Now, I can use grep for my desired result:

my @pairs = grep {$_ =~ /\S/} split /([a-z]+[^a-z]+)/, $str;

But I was wondering if there was a more elegant solution to this problem.

+5  A: 

Don't know if it is an elegant solution, you can use matching with the /g modifier:

my @pairs = $str =~ /(\w+\s+\d+)/g;
eugene y
+12  A: 

Why split them as pairs? Just get a list of words then take them by twos.

 my @words = split /\s+/, $str;
 while( @words ) {
     my( $first, $second ) = splice @words, 0, 2;
     ...;
     }

If you want a hash, it's even simpler:

 my %pairs = split /\s+/, $str;

I find that much easier to understand and pass on to another programmer than a regex.

brian d foy
+1 for the hash solution, talk about 'outside the box' thinking...
Zaid
Hashes aren't out of the box at all. Almost anytime someone says "pair", you should hear "hash" :)
brian d foy
Perhaps it's better to use `split ' ', $str` if skipping leading and trailing whitespace is what you want. Also it is said to have some special optimizations.
codeholic