tags:

views:

128

answers:

7

I have a string of the form:

"jflsdlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   "

Toward the end it contains eight digits. There may be spaces between the digits, but there are always eight digits in the end. How do we obtain each of these digits separately using Perl?

A: 
if (m/(\d)\s*(\d)\s*(\d)\s*(\d)\s*(\d)\s*(\d)\s*(\d)\s*(\d)\s*$/) {
    ($d1, $d2, $d3, $d4, $d5, $d6, $d7, $d8) = ($1, $2, $3, $4, $5, $6, $7, $8);
}
rsp
some helping text please. it seems very complex to me
iamrohitbanga
That's an amazing amount of work for a simple task. Whenever you do that much work, you have to ask yourself if you're doing it right.
brian d foy
Wow. Way to code like line noise :)
David Precious
This is exactly what was asked, unlike the other answers. The OP asked for the 8 trailing digits seperately and this does that in 2 expressions.
rsp
Unlike the other answers? My answer does it just fine, and so does the answer from depesz. That other answer got it right doesn't mean that you didn't do too much work. :)
brian d foy
depesz's answer only works if the input is as expected. At the time of the previous comment all answers resulted in a string containing the digits or an array, not seperately as asked for. I agree that these 2 lines dont look nice, but it works. I suspect that you wouldnt't mind them for 3 digits instead of 8.
rsp
I would mind them for two digits even. Never repeat structure when you don't have to.
brian d foy
+2  A: 

/(\d\s*){8}$/

should do it. don't forget to strip out the whitespace in each of the captures.

ennuikiller
Amarghosh
Change the \s+ to \s* to make spaces optional, and then `split //` the result to get each digit individually.
jrockway
this is what i am doing it does not work.$str1 = "slfjsdlwer312fjk 23423 355";$str2 = /(\d\s*){8}$str1/;print str2does not work.
iamrohitbanga
`=` is not the same as `=~`
friedo
This will not give the digits seperately.
rsp
`/((\d\s*){8})$/` Might be better.
Brad Gilbert
+3  A: 

The easiest thing to do conceptually is to apply a normalization step to the string before you extract the digits. In the example you've shown, that might be as easy as just removing all of the whitespace first. In case you need the string later, I'll do that to a copy. Once you have the normalized copy, just grab the eight digits at the end:

my $string = "jflsdlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   ";
my $copy = $string;

$copy =~ s/\s+//g; # "normalize" string

my @digits;
if( $copy =~ m/(\d{8})\z/ ) 
    {
    @digits = split //, $1
    }

print "digits are @digits\n";
brian d foy
+6  A: 

Get input:

my $input = "jflsdlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   ";

now, extract all digits:

my @all_digits = $input =~ /(\d)/g;

Now, get the last 8 from it:

my @last_8_digits = @all_digits[-8..-1];
depesz
+4  A: 

get rid of non-digits and then take substring from the back

$string="jflsdlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   ";
$string =~ s/[^[:digit:]]//g;
print substr ( $string ,-8);
ghostdog74
This is slightly fragile for the odd case where you don't end up with 8 digits after the normalization. I had considered this too. Also, if you just want 0-9, the locale expansion of the POSIX character class might leave behind more than you intend.
brian d foy
This will match "a1b2c3d4e5f6g7h8i" too, giving an answer where there is none. On top of that, the digits are not delivered seperately.
rsp
yes, i did consider that as well, but OP says he always have 8 digits at the end in his post, therefore let's not jump too far ahead for the moment, shall we
ghostdog74
People say all sorts of things, and it's so easy to check. Your definition of far ahead must be very short indeed. :)
brian d foy
+1  A: 

Here's a solution that should work with any input

my $input = "dlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   ";

if  ($input =~ /((?:\d\s*){8})$/) {  # grab last 8 digits and any space

    my @nums = split /\s+|/ => $1;   # throw away space and separate each digit

    print "@nums\n";  # 2 4 4 6 1 4 2 5
}
Eric Strom
+1  A: 

You can use the following code

my $string="jflsdlf f fas253k46l ;sf635jsf sd;lfwio sfkljflsk-=fsd f 24461 425   ";
 my @array=split(/ / , $string);
 print "$array[$#array-1]";
 print "$array[$#array]\n";
muruga