I have a string that is eight numbers and I would like to split it into two. I know that I could do it with substring but split seemed like a more logical choice. One way I did it was this:
my $thing = '12340019';
$thing = s/(\d{4})(\d{4})/$1 $2/;
my @splat = split(/ /, $thing);
But that doesn't really seem like the best way to do it. I figured that I should be able to get the effect by using split by itself and asking it to split on 4 numbers, but I couldn't get it to work. Also how would I go about changing '0019' into 19. Is sprintf the only (or best) way to accomplish that.
Thanks
my $thing = '12340019';
my @splat = $thing =~ m/\d{4}/g;
my $num = '0019'; $num = int $num;
Also my @splat = $thing =~ m/\d{4}/g; only sets @splt = ('1234');
That's funny, because:
my $thing = '12340019';
my @splat = $thing =~ m/\d{4}/g;
print Dumper \@splat;
__END__
$VAR1 = [
'1234',
'0019'
];
Cheers, Sören
Well the number changes each time so I couldn't just use int '0019'.uh? so what's the problem? use int $num, like i showed you.
Also my @splat = $thing =~ m/\d{4}/g; only sets @splt = ('1234');see Happy-the-monk's answer. maybe your perl is broken.
It's not that I thought it only worked on the string '0019'. When I had first typed you code and did:
foreach (@splat) { print $_, "\n" }
I only saw 1234 printed, so I figured you then wrote the int '0019' because @splat = $thing =~ m/\d{4}/g; only sets the first one. However, I did it again, I really don't know what I changed, but it worked this time.
Thanks. And sorry for the confusion.
See also Adding formatting to a string posted today.
Cheers, Sören
Did you want integers?
my $thing = '12340019';
my @splat = map {int $_} $thing =~ /(\d{4})/g
my $thing = '12340019';
my @num01 = map{ int } $thing =~ m/(\d{4})/g;
#!/usr/local/bin/perl -w
use strict;
my $number = '00120034';
# split at the position that has 4 digits
# behind and 4 digits ahead
my ($n1, $n2) = split /(?<=\d{4})(?=\d{4})/, $number;
print "$n1, $n2\n";
# strip leading 0's
($n1, $n2) = map { int $_ } ($n1, $n2);
print "$n1, $n2\n";
0012, 0034 12, 34
{
local $_ = $amount;
/\./ ? s/(?<=\d)(?=(\d{3})+(?:\.))/,/g : s/(?<=\d)(?=(\d{3})+(?!\d))/,/g;
$amount = $_;
}
This technique is very useful
Lookahead and lookbehind are both very useful indeed, but I think your example is better solved with a sexeger:
$amount = reverse $amount;
$amount =~ s/(\d{3})/$1,/g;
$amount = reverse $amount;
Update: oops, I guess my example doesn't commafy a floating-point number, now does it? Oh well. At least maybe someone will learn about sexegers who didn't know about them. 8^)
Here's another stab:
s{(?
We're not really tightening our belts, it just feels that way because we're getting fatter.
[doc://split] is best used when you have a separator of some sort to split on. In this case there is no separator - you have a bunch of things packed together - so you'd probably be better off with [doc://unpack]:
my @splat = unpack '(A4)*', $thing;
That is: unpack this string into (4-character substrings) as many as you can find. (If there can only be two such substrings, you can replace the '*' with '2' to specify that.) Note that this is just dealing with characters, it doesn't know anything about digits - if you need to locate the digits in the string first, you probably want a regular expression for that.
Once you have the right digits separated out, removing leading zeros is as simple as getting perl to treat it as a number. A couple of common idioms for doing that are:
$num = int($string); $num = $string + 0;
With [doc://map] you can apply that transformation to the stream of strings on its way into the array:
my @splat = map $_ + 0, unpack '(A4)*', $thing;
Hope this helps,
Hugo
print join ":", map {sprintf("%d",$_)} unpack("A4A4",shift);
perlmonks.org content © perlmonks.org and debiandude, Happy-the-monk, hv, pbeckingham, periapt, revdiablo, Roger, Roy Johnson, tinita, wufnik
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03