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

Hi,

was wondering what would be the best way to capture a number from a string that has both words and numbers.

The string is compoased of pairs of data that is a name (which could be more than one word) and a number associated with it, and each pair is delimited with a colon. For my example I'd like to capture only the first number from the first data pair in the string.

String looks like :

Happy Joy 002245:Dubloons 002256:hats 034523:paper clips 232344:pants 233394

So I just need to grab the first number 002245 from the string. I've tried splitting the data on a colon and then trying to capture the number but for some reason its not working. Any simple suggestions? Thanks!

sorry about not including what I was doing earlier....here's what I was attempting:

$string = Happy Joy 002245:Dubloons 002256:hats 034523:paper clips 232 +344:pants 233394; @items = split (/:/, $string); $number = split(/\d+/, $items[0]);

So instead of getting a value in $number I was getting just a "1" or "2". I couldn't figure out how I could use a regex just to grab what I needed. But I got davidos to work for me with: $number = $1 if $items[0]=~ m/(\d+)/;

Thanks guys!

Edited by Chady -- fixed formatting.

Replies are listed 'Best First'.
Re: getting a number from a string
by davido (Cardinal) on Jan 05, 2004 at 04:10 UTC
    You didn't show any example of what was "not working", but this does.

    my $string = "Happy Joy 002245:Dubloons 002256:hats 034523:paper clips + 232344:pants 233394"; my @items = split /:/, $string; my $number; $number = $1 if $items[0] =~ m/(\d+)/; print $number, "\n";

    Make sure not to use $number if a match didn't occur. Also, this method provides you with every item. I know you mentioned only wanting the first. If that's all you'll ever need, you can just do this:

    $number = $1 if $string =~ m/(\d+):/; print $number, "\n";

    Cheers!


    Dave

      thanks! It worked.
Re: getting a number from a string
by BrowserUk (Patriarch) on Jan 05, 2004 at 04:49 UTC
    my $s= 'Happy Joy 002245:Dubloons 002256:hats 034523:paper clips 23234 +4:pants 233394'; my %lookup = map{ m[(^.*)\s+(\d+$)] } split ':', $s; print "$_ => $lookup{ $_ }" for keys %lookup; paper clips => 232344 Dubloons => 002256 Happy Joy => 002245 hats => 034523

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

Re: getting a number from a string
by graff (Chancellor) on Jan 05, 2004 at 04:17 UTC
    If you just need to grab the first numeric substring from the total string, this will do it:
    $_ = "Happy Joy 002245:Dubloons 002256:hats 034523:paper clips 232344: +pants 233394"; my $first_number = ( /(\d+)/ ); print "$first_number\n";
    If you need to get each of the numeric substrings, make it an array assignment and add the "g" modifier to the regex:
    my @numbers = ( /(\d+)/g ); print join $/, @numbers, "";
    And, the next time you say "I've tried ....", show us the actual code that you tried, so we can see why you couldn't get it to work. That makes it more educational.
Re: getting a number from a string
by Roger (Parson) on Jan 05, 2004 at 05:33 UTC
    The follow example builds the hash lookup table with a single regular expression with capture, using the @array = $str =~ /(regex)/g idiom. It is a useful technique to master.

    use strict; use warnings; use Data::Dumper; my $str = 'Happy Joy 002245:Dubloons 002256:hats 034523:paper clips 23 +2344:pants 233394'; my %capture = $str =~ /(\D*?)\s+(\d+):?/g; print Dumper(\%capture);
    And the output -
    $VAR1 = { 'pants' => '233394', 'hats' => '034523', 'Happy Joy' => '002245', 'Dubloons' => '002256', 'paper clips' => '232344' };
Re: getting a number from a string
by jonadab (Parson) on Jan 05, 2004 at 11:50 UTC

    This may be more than you need, but ISTR that one of the modules on the 2003 Perl Advent Calendar (sorry; I don't recall which day) was a module of ready-made regular expressions for common parsing tasks. One of them was for parsing numbers. It's robust enough to handle most common number formats. If you find that the simple solutions here miss some numbers that are formatted a little differently (e.g., have signs, decimal points, or whatever), you may want to look into that.

    However, if all your numbers are plain regular ordinary vanilla-type natural numbers, the solutions above should work fine. I mostly included this suggestion for the benefit of someone who might find this thread in SuperSearch later and have more advanced needs.

    update: valdez reminded me of the name of the module in question. It's Regexp::Common.


    $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/