Perl Regex: Need help on a way to split string into groups matching a pattern
I need to split this string to an array:
$string = "9583526578','9583636523','9673522574','9183556528','9983023378";
Here's how I want my array to look like after splitting:
@foo = [
[9583526578, 9583636523],
[9673522574, 9183556528],
[9983023378]
]
As you might have noticed, I need to split this string into groups of n (2 in this example) but still consider remainder if it doesn't match with n.
How can this be done in Perl?
I've done my research and experimentations but 开发者_如何学Ccan't seem to get it right after a couple of hours.
Thanks for your time! :)
If you can trust they're all integers, extraction is easy. Just grab all the integers.
my @numbers = $string =~ /(\d+)/g;
Then splitting them into pieces of two...
push @matrix, [splice @numbers, 0, 2] while @numbers;
Not as memory efficient as doing it in place, but simple code (if you grok list processing).
If the only reason you're splitting them into pairs is to process them in pairs, you can destructively iterate through the array...
while( my @pair = splice @numbers, 0, 2 ) {
...
}
Or you can iterate in pairs in one of the rare valid uses of a 3-part for loop in Perl.
for(
my $idx = 0;
my @pair = @numbers[$idx, $idx+1];
$idx += 2;
)
{
...
}
Finally, you can get fancy and use perl5i.
use perl5i::2;
@numbers->foreach( func($first, $second) { ... } );
You can also use List::MoreUtils natatime
.
First split on "','" to give you an array, then group the elements as desired.
I would recommend using regex to retrieve the numbers using '([0-9]+)' and just manually building @foo. Or as @MRAB suggested, split is even more straight-forward. Any reason you are aiming at Regex for this?
Tons of different ways. Here's one:
$foo[0] = []; # assuming you really meant an array of arrays of arrays as you showed
while ($string =~ m/([0-9]++)[^0-9]*+([0-9]++)?/g) {
push @{ $foo[0] }, [ $1, $2 // () ];
}
(Did you really mean an array containing just one reference to an array of arrayrefs?)
This should be a reasonably close fit to your desired behavior:
my @foo;
push @foo, [ $1, $2 // () ] while $string =~ / (\d+) (?: \D+ (\d+) ) ? /gx;
精彩评论