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

Hi,

I have a feeling there is a much much succinct way of handling this.

In this example $val could be any number of digits between 1 and 8 with a comma separating every third; also, the text is found within a much larger piece of text (as opposed to the simple example used here).

I'm looking for a numeric value followed by " view" and then want to remove any commas.

Thanks!

my $num_views = -1; my $val = "23,452,789 views"; if ($val =~ /([\d]*),([\d]*),([\d]*) views/) { $num_views = ($1 * 1000000) + ($2 * 1000) + $3; print "# Matched number of views [$num_views].\n"; } else { if ($val =~ /([\d]*),([\d]*) views/) { $num_views = ($1 * 1000) + $2; print "# Matched number of views [$num_views].\n"; } else { if ($val =~ /([\d]*) views/) { $num_views = $1; print "# Matched number of views [$num_views].\n"; } else { print "# Error.\n"; } } }

Replies are listed 'Best First'.
Re: How to consolidate regex's?
by BrowserUk (Patriarch) on Feb 04, 2010 at 23:31 UTC

    Try

    $s = "23,452,789 views";; $s =~ m[((?:\d+,)?(?:\d+,)?\d+) views] and ( $n = $1 ) =~ s[,][]g and +print $n;; 23452789 $s = "452,789 views";; $s =~ m[((?:\d+,)?(?:\d+,)?\d+) views] and ( $n = $1 ) =~ s[,][]g and +print $n;; 452789 $s = "789 views";; $s =~ m[((?:\d+,)?(?:\d+,)?\d+) views] and ( $n = $1 ) =~ s[,][]g and +print $n;; 789

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: How to consolidate regex's?
by jwkrahn (Abbot) on Feb 04, 2010 at 23:13 UTC
    my $num_views = -1; my $val = "23,452,789 views"; if ( $val =~ /(\b[\d,]+\b) views/ ) { ( $num_views = $1 ) =~ tr/,//d; print "# Matched number of views [$num_views].\n"; } else { print "# Error.\n"; }
Re: How to consolidate regex's?
by jethro (Monsignor) on Feb 04, 2010 at 23:09 UTC

    If you don't mind accepting 23,,4,5,2789 too, this combo will work:

    if ($val =~ /([\d,]*) views/) { $num_views= $1; $num_views=~s/,//g;

    UPDATE: Thanks to GrandFather the 'fi' (which only the NSA knows about) was changed to 'if'

      If you don't mind accepting 23,,4,5,2789 too

      The match op can be used to capture and it can be used to validate. It can't always do both at the same time, and even when it can, sometimes the smart thing to do is to not care about validation.

      As long as it does the right thing for proper inputs and it doesn't do anything overly bad for bad inputs, you're good.

      [ I forget that too often ]

Re: How to consolidate regex's?
by samarzone (Pilgrim) on Feb 05, 2010 at 13:58 UTC
    If you want to be very strict about the pattern of the string (including the comma).
    perl -e '$a = "1,234,340 views";print "$1\n" if($a =~ /^((?:\d{1,3})?( +?:,\d{3})*) views$/);'
    I think using "^" will speed up things a bit (although a few nanoseconds won't make much difference) when compared to similar regex without "^".