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

I am using this in an if statement. It does check for valid phone number entry:
The problem is if someone enters 22- 234 2324 it doesnt check the "-". Please advise if anyone has a better phone number regular expression validation. Iam using this to verify a valid phone number entry on my form.
/[^((\d\s?[\(\-\.\s]\s?)?\d{3}\s?[\)\-\.\s]?)?\s?\d{3}\s?[\.\-\s]?\s?\ +d{4}$]/

Replies are listed 'Best First'.
Re: Phone reg expression
by particle (Vicar) on Apr 18, 2003 at 17:32 UTC
      Hi particle.
      Regexp::Common was going to be my suggestion, but i can't figure out what Regexp::Common::URI::tel wants (or if that is even the right class to use):
      use Regexp::Common qw /URI/; while (<DATA>) { /$RE{URI}{tel}/ and print "$_ contains a telephone URI.\n"; } __DATA__ 555-5555 555-555-5555 (555) 555-5555
      any thoughts? anyone? :)

      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)
      
        tel:+12345 tel:+358-555-1234567 tel:456-7890;phone-context=213 tel:456-7890;phone-context=X-COMPANY-NET tel:+1-212-555-1234;tsp=terrifictelecom.com tel:+1-212-555-1234;tsp=terrifictelecom.com;phone-context=X-COMPANY-NE +T tel:+358-555-1234567;postd=pp22 tel:0w003585551234567;phone-context=+3585551234 tel:+1234567890;phone-context=+1234;vnd.company.option=foo tel:+1234567890;phone-context=+1234;vnd.company.option=%22foo%22 tel:+1234;option=%22!%22 tel:+1234;option=%22%5C%22%22 tel:+1234;option=%22%5C!%22 tel:+1234;option=%22bar%22 tel:+456-7890;phone-context=213;phone-context=213 tel:456-7890;phone-context=213;phone-context=213 tel:+123-456-789;isub=123(456) tel:+123456;postd=***

        For details, see RFC 2806.

        Abigail

      There are no patterns for phone numbers in Regexp::Common yet, for the simple reason I have not found a specification of phone numbers for any country yet.

      For instance, a regexp that allows for 7 or 11 digit phone numbers would be incorrect for the North America Plan, as that would reject for instance 911.

      Abigail

        For the obsessively curious, there's a lot of interesting (and apparently authoritative) information about U.S. and Canadian phone-number standards at NANPA, the North American Numbering Plan Adminstration. It covers arcana such as the so-called N11 numbers (911, 411, etc.), potentially valid area codes (/2-90-80-9/, except /\d11/, /37\d/, and /96\d/), vertical services codes (112?\d\d or \*2?\d\d), and so on. It even alludes to what will happen when North America eventually moves to 11-digit phone numbers (i.e., 4-digit area codes). Now there's a scary thought for anyone who's been writing phone-number validation code that assumes a 3-3-4 format.

                $perlmonks{seattlejohn} = 'John Clyman';

Re: Phone reg expression
by jasonk (Parson) on Apr 18, 2003 at 17:31 UTC

    This is the best regexp to check for a valid phone number: /\d/. Seriously, are you going to refuse to accept phone numbers that include extensions, international numbers, and all the other numbers that aren't going to match your regular expression? If that is really what you want, then just remove all the non-numeric characters, and ensure you have 10 or 11 digits left (so you get both 800-123-4567 and 1-800-123-4567).  $number =~ s/\D//g; $number =~ /^\d{10,11}$/;


    We're not surrounded, we're in a target-rich environment!
      sub ValidPhone { ($phone)=@_; if($phone =~ m/^[\d()-\.]+$/) { $phone =~ s/[\D]*//g; if($phone =~ m/\d{7,11}/) { return 1; } } else { return 0; } return 0; }
Re: Phone reg expression
by cciulla (Friar) on Apr 18, 2003 at 18:00 UTC

    Sniff... Sniff... I caught a whiff of homework...

    It appears that you're being a tad too lienient with your users by allowing them to enter a phone number in any way they please. Provide some guidance to your users!! That is to say, provide a separate <input> tag for each element you want to capture and validate:

    <b>Please enter your phone number:<b> <table border="1"> <tr> <th>Area Code</th> <th>Phone Number</th> </tr> <tr> <td>(<input type="text" name="area_code" size="3" maxlength="3">) </td> <td> <input type="text" name="phone_exchange" size="3" maxlength="3"> -<input type="text" name="phone_number" size="4" maxlength="4"> </td> </tr> </table>

    So, you've decreased the complexity of your validation routine at the cost of a few more fields and the tiniest bit of pain for your users.

    area code: /^\d{3}$/

    phone exchange: /^\d{3}$/

    phone number: /^\d{4}$/

    HTH.

    C2

      This technique still excludes international numbers and extensions. Good luck contacting people in office buildings without being able to support extensions.


      We're not surrounded, we're in a target-rich environment!

        Yeah, you're right.

        However, any developer worth his salt could extrapolate based upon the given code. The points I was attempting to convey were:

        • Provide guidance to your users
        • Keep it simple