campbell has asked for the wisdom of the Perl Monks concerning the following question:

O enlightened ones

I would like to take each member of an array, and remove anything in that member that is not a digit.

I tried this:

foreach $n(@array) { $num=s/\D//i; print $num; }
but this did not work: I just ended up with nothing. What am I doing wrong!?

Yours humbly,
Campbell

Replies are listed 'Best First'.
(jeffa) Re: Removing non digits
by jeffa (Bishop) on Jul 23, 2003 at 15:00 UTC
    Try this: use strict;

    Then you will see that you really meant to code:

    foreach my $num (@array) { $num =~ s/\D//g; print $num; }
    Also, since \D is ANY non-digit, i removed the i modifier and replaced it with the g modifier so that you will remove more than just the first encountered non-digit. Further more, when using regular expressions, use the =~ operator and not the = operator. Hope this helps. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Removing non digits
by perlplexer (Hermit) on Jul 23, 2003 at 15:02 UTC
    Your loop variable is "$n", not "$num".
    I'd do:
    tr/0-9//cd for @array;
    --perlplexer
Re: Removing non digits
by dga (Hermit) on Jul 23, 2003 at 15:09 UTC

    The i does case insensitive matching and since you are removing all upper and lower case letters it will just slow things down (if it does anything at all)

    $n =~ s/\D+//g;

    This is closer to what you want. This says remove all groups of things that aren't numbers and the /g says to keep doing it until the string is all gone. The =~ says that what follows is a Regular Expression to be applied to the lvalue ($n in this case). I used $n since that was the looping variable in your foreach.I do not know in this case if \D+ is more efficient than just \D which would remove the non digits one at a time.

    Also note that this will modify the values in the array such that it will be changed as a result of the foreach.

    Also tr would be faster.

    $n =~ tr/0-9//cd;

    This says remove from $n anything that isn't a 0-9. c says complement the set given ie not 0-9 and d says delete things in the match list that do not appear in the replacement list.

    Update: Oops as noted the searchpattern is already taken to be a character list so the brackets do not work like in a RE. mea culpa

      $n =~ tr/[0-9]//cd;

      That should be tr/0-9//cd; (no brackets) because tr/// expects a character class, not a regular expression.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: Removing non digits
by The Mad Hatter (Priest) on Jul 23, 2003 at 15:10 UTC
    Just to show another way of doing it, I'd probably do:
    @array = map { s/\D//g; $_ } @array;