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

Hi Monks,
I am trying to check for phone number input using the regular expression below, but I can't understand why it isn't matching, any help or suggestions in how I could improve my code to check phone number format like:
(555) 324-1233
555 - 324-1234
1 555 342-1234

It may or may not have spaces in between or dashes as well but looking at the regular expression that I have it should be very flexible in matching phone members.
Thanks for the help!
$phone_number = "(555) 324-1233"; if ($phone_number =~/^[(]?(d{0,3})[)]?[s]?[-]?(d{3})[s]?[-]?(d{4})[s]? +[x]?(d*)$/){ #if ($phone_number =~/^(\D*\d{3}?)(\D*\d{3}?)(\D*\d{4}?)(\D*$)/){ #// we have a match, dump sub-patterns to $matches $phone = $1; #// original number $area_code = $2; #// 3-digit area code $exchange = $3; #// 3-digit exchange $number = $4; #// 4-digit number $extension = $5; #// extension print "**** $phone ** $area_code ** $exchange ** $number ** $exten +sion ***** "; }else{print "no match";}

Replies are listed 'Best First'.
Re: Regular Expression Help
by Roy Johnson (Monsignor) on Mar 03, 2005 at 16:54 UTC
Re: Regular Expression Help
by Tanktalus (Canon) on Mar 03, 2005 at 16:19 UTC

    Here's the code I tested ...

    use strict; my @p = ( '(555) 324-1233', '555 - 324-1234', '555 - 324-1234x204', '1 555 342 1234', ); my $re = qr/(?:1\s*)?\(?(\d{3})\)?\s*-?\s*(\d{3})[\s-]?(\d{4})(?:x(\d+ +))?/; for my $p (@p) { if ($p =~ $re) { printf "phone number = %s\n" . "area code = %s\n" . "exchange = %s\n" . "number = %s\n" . "extention = %s\n", $p, $1, $2, $3, $4 ? $4 : 'none'; } else { print "[$p] doesn't look like a phone number to me\n"; } }

    Output:

    phone number = (555) 324-1233 area code = 555 exchange = 324 number = 1233 extention = none phone number = 555 - 324-1234 area code = 555 exchange = 324 number = 1234 extention = none phone number = 555 - 324-1234x204 area code = 555 exchange = 324 number = 1234 extention = 204 phone number = 1 555 342 1234 area code = 555 exchange = 342 number = 1234 extention = none
Re: Regular Expression Help
by ikegami (Patriarch) on Mar 03, 2005 at 16:21 UTC

    Might be more versatile and easier to read to do:

    $_ = $phone_number; s/[() -]//g; # Remove seperators, or #s/[^0-9xX]//g; # Remove non-digits. s/^1//; die("Unrecognize phone number format.\n") unless /^(\d{3})(\d{3})(\d{4})(?:[xX](\d+))$/; $area_code = $1; $exchange = $2; $number = $3; $extension = $4; $clean_phone = join('-', $area_code, $exchange, $number); $clean_phone .= "x$extention" if defined $extention;

    By the way, both yours and mine only work with North American phone numbers.

Re: Regular Expression Help
by davido (Cardinal) on Mar 03, 2005 at 16:15 UTC

    d and  s are not metacharacters.  \d and  \s are. That's one problem.


    Dave

Re: Regular Expression Help
by prasadbabu (Prior) on Mar 03, 2005 at 16:15 UTC
    You have used [s]? which is wrong, you should use [\s]? for space.

    Prasad

      I'd just like to point out \s by itself does not need to be in a character class. \s will work just as well as [\s]. It may also make the expression more robust to use \s* as opposed to [\s]?.

      May the Force be with you