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

Hiya monks, I have to read through csv files and looking for one particular line. Then I have to grep all the numbers behind it. Here is a snippet...
$string = 'Total requests:,20,30,40,50,60' #the list could go on if ($string =~ m/Total requests:,*?(\d+),(\d+),(\d+),(\d+)/) #don't know how to do this if to grep all the numbers in that line
The thing is I have no clue how to match all the instances of (\d+) -- maybe with '(,\d+)+'? And I would like to push all the matched numbers into an array using $1, $2, $3.... in order, if that is possible... Any help is appreciated

Replies are listed 'Best First'.
Re: regex help
by kennethk (Abbot) on Nov 12, 2009 at 20:59 UTC
    Is there a particular reason this need to be done all at once? Assuming you have a good reason for not using one of the many CSV-parsing modules (e.g. Text::CSV), it would be a lot clearer to do something like:

    if ($string =~ m/Total requests:/) { @array = split /,/, $string; }

    rather than trying to do a match and capture at the same time. If you have your heart on capturing things in a regular expression, you could do

    if ($string =~ m/Total requests:/) { @array = $string =~ /(\d+)/g; }

    But I'm willing to bet that your life would be easier with just a CSV-parsing module.

    Incidentally, your suggestion of (\d)+ will not work because you will repeatedly overwrite your result and hence will only get the last match (60 in your example).

Re: regex help
by JadeNB (Chaplain) on Nov 12, 2009 at 23:29 UTC
    As kennethk and ikegami point out, the crucial thing to realise is this snippet from Matching in list context:
    If the /g option is not used, m// in list context returns a list consisting of the subexpressions matched by the parentheses in the pattern, i.e., ($1 , $2 , $3 ...). (Note that here $1 etc. are also set, and that this differs from Perl 4's behavior.) When there are no parentheses in the pattern, the return value is the list (1) for success. With or without parentheses, an empty list is returned upon failure.
    That's the motivation for the seemingly strange @array = $string =~ m/$regex/ pattern (which parses as @array = ($string =~ m/$regex/)) in kennethk's post.
Re: regex help
by ikegami (Patriarch) on Nov 12, 2009 at 21:06 UTC
    if (my @totals = $string =~ m/Total requests:,*?(\d+),(\d+),(\d+),(\d+ +)/)
Re: regex help
by oha (Friar) on Nov 13, 2009 at 15:01 UTC
    my @out = /,(\d+)/g;
    works for the case you said, or if you require to match against "Total request":
    my @out = grep { defined } /(?:Total requests:|,(\d+))/g;