Skip to content

Instantly share code, notes, and snippets.

@lamguy
Forked from wpsmith/sanitize_phone.php
Last active August 29, 2015 14:14
Show Gist options
  • Select an option

  • Save lamguy/7524768844e916e04df9 to your computer and use it in GitHub Desktop.

Select an option

Save lamguy/7524768844e916e04df9 to your computer and use it in GitHub Desktop.

Revisions

  1. @wpsmith wpsmith created this gist Jun 5, 2014.
    32 changes: 32 additions & 0 deletions sanitize_phone.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    <?php

    function sanitize_phone( $phone, $international = false ) {
    $format = "/(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/";

    $alt_format = '/^(\+\s*)?((0{0,2}1{1,3}[^\d]+)?\(?\s*([2-9][0-9]{2})\s*[^\d]?\s*([2-9][0-9]{2})\s*[^\d]?\s*([\d]{4})){1}(\s*([[:alpha:]#][^\d]*\d.*))?$/';

    // Trim & Clean extension
    $phone = trim( $phone );
    $phone = preg_replace( '/\s+(#|x|ext(ension)?)\.?:?\s*(\d+)/', ' ext \3', $phone );

    if ( preg_match( $alt_format, $phone, $matches ) ) {
    return '(' . $matches[4] . ') ' . $matches[5] . '-' . $matches[6] . ( !empty( $matches[8] ) ? ' ' . $matches[8] : '' );
    } elseif( preg_match( $format, $phone, $matches ) ) {

    // format
    $phone = preg_replace( $format, "($2) $3-$4", $phone );

    // Remove likely has a preceding dash
    $phone = ltrim( $phone, '-' );

    // Remove empty area codes
    if ( false !== strpos( trim( $phone ), '()', 0 ) ) {
    $phone = ltrim( trim( $phone ), '()' );
    }

    // Trim and remove double spaces created
    return preg_replace('/\\s+/', ' ', trim( $phone );
    }

    return false;
    }
    47 changes: 47 additions & 0 deletions test-phone.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    $array = array(
    '-234-567-8901',
    '1-234-567-8901',
    '1-234-567-8901 x1234',
    '1-234-567-8901 ext1234',
    '1 (234) 567-8901',
    '1.234.567.8901',
    '1/234/567/8901',
    '12345678901',
    '(+351) 282 43 50 50',
    '90191919908',
    '555-8909',
    '001 6867684',
    '001 6867684x1',
    '1 (234) 567-8901',
    '1-234-567-8901 x1234',
    '1-234-567-8901 ext1234',
    '1-234 567.89/01 ext.1234',
    '1(234)5678901x1234',
    '(123)8575973',
    '(0055)(123)8575973',
    '(123)456-7890',
    '(123)-456-7890',
    '(123) 456-7890',
    '(123) 456-7890 x123',
    '12 1234 123 1 x1111',
    '12 12 12 12 12',
    '12 1 1234 123456 x12345',
    '+12 1234 1234',
    '+12 12 12 1234',
    '+12 1234 5678',
    '+12 12345678',
    '(123)456789',
    '(123456789',
    '(123 456 789',
    '(123.456.789',
    '(123-456-789',
    '123)456789',
    '123) 456 789',
    '123).456.789',
    '123)-456-789',
    );

    foreach( $array as $phone ) {
    echo $phone . ': ';
    echo "\t\t" . sanitize_phone( $phone ) . "\n";
    }
    230 changes: 230 additions & 0 deletions z-alternative-php.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,230 @@
    <?php

    function validate_telephone_number($number, $formats) {
    $format = trim(ereg_replace("[0-9]", "#", $number));

    return (in_array($format, $formats)) ? true : false;
    }

    /* Usage Examples */

    // List of possible formats: You can add new formats or modify the existing ones

    $formats = array(
    '###-###-####',
    '####-###-###',
    '(###) ###-###',
    '####-####-####',
    '##-###-####-####',
    '####-####',
    '###-###-###',
    '#####-###-###',
    '##########',
    );

    $numbers = array(
    '08008-555-555',
    '123-555-555',
    '1800-1234-5678',
    '(800) 555-123',
    '1234567890',
    );
    foreach ( $numbers as $number ) {

    if ( validate_telephone_number( $number, $formats ) ) {
    echo $number.' is a valid phone number.';
    echo "<br />";
    }

    }


    function sanitize_phone( $phone, $international = false ) {
    $phone = trim( $phone );
    $phone = preg_replace( '/\s+(#|x|ext(ension)?)\.?:?\s*(\d+)/', ' ext \3', $phone );

    $us_number = preg_match( '/^(\+\s*)?((0{0,2}1{1,3}[^\d]+)?\(?\s*([2-9][0-9]{2})\s*[^\d]?\s*([2-9][0-9]{2})\s*[^\d]?\s*([\d]{4})){1}(\s*([[:alpha:]#][^\d]*\d.*))?$/', $phone, $matches );

    if ( $us_number ) {
    return 'US: ' . $matches[4] . '-' . $matches[5] . '-' . $matches[6] . ( !empty( $matches[8] ) ? ' ' . $matches[8] : '' );
    }

    if ( ! $international ) {
    /* SET ERROR: The field must be a valid U.S. phone number (e.g. 888-888-8888) */
    return false;
    }

    $valid_number = preg_match( '/^(\+\s*)?(?=([.,\s()-]*\d){8})([\d(][\d.,\s()-]*)([[:alpha:]#][^\d]*\d.*)?$/', $phone, $matches ) && preg_match( '/\d{2}/', $phone );

    if ( $valid_number ) {
    return trim( $matches[1] ) . trim( $matches[3] ) . ( !empty( $matches[4] ) ? ' ' . $matches[4] : '' );
    }

    /* SET ERROR: The field must be a valid phone number (e.g. 888-888-8888) */
    return false;
    }

    function formatPhoneNumber( $s ) {
    $rx = "/
    (1)?\D* # optional country code
    (\d{3})?\D* # optional area code
    (\d{3})\D* # first three
    (\d{4}) # last four
    (?:\D+|$) # extension delimiter or EOL
    (\d*) # optional extension
    /x";
    preg_match($rx, $s, $matches);
    if(!isset($matches[0])) return false;

    $country = $matches[1];
    $area = $matches[2];
    $three = $matches[3];
    $four = $matches[4];
    $ext = $matches[5];

    $out = "$three-$four";
    if(!empty($area)) $out = "$area-$out";
    if(!empty($country)) $out = "+$country-$out";
    if(!empty($ext)) $out .= "x$ext";

    // check that no digits were truncated
    // if (preg_replace('/\D/', '', $s) != preg_replace('/\D/', '', $out)) return false;
    return $out;
    }

    function format_phone_number ( $mynum, $mask ) {
    /*********************************************************************/
    /* Purpose: Return either masked phone number or false */
    /* Masks: Val=1 or xxx xxx xxxx */
    /* Val=2 or xxx xxx.xxxx */
    /* Val=3 or xxx.xxx.xxxx */
    /* Val=4 or (xxx) xxx xxxx */
    /* Val=5 or (xxx) xxx.xxxx */
    /* Val=6 or (xxx).xxx.xxxx */
    /* Val=7 or (xxx) xxx-xxxx */
    /* Val=8 or (xxx)-xxx-xxxx */
    /*********************************************************************/
    $val_num = validate_phone_number ( $mynum );
    if ( !$val_num && !is_string ( $mynum ) ) {
    echo "Number $mynum is not a valid phone number! \n";
    return false;
    } // end if !$val_num
    if ( ( $mask == 1 ) || ( $mask == 'xxx xxx xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '$1 $2 $3'." \n", $mynum);
    return $phone;
    } // end if $mask == 1
    if ( ( $mask == 2 ) || ( $mask == 'xxx xxx.xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '$1 $2.$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 2
    if ( ( $mask == 3 ) || ( $mask == 'xxx.xxx.xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '$1.$2.$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 3
    if ( ( $mask == 4 ) || ( $mask == '(xxx) xxx xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '($1) $2 $3'." \n", $mynum);
    return $phone;
    } // end if $mask == 4
    if ( ( $mask == 5 ) || ( $mask == '(xxx) xxx.xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '($1) $2.$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 5
    if ( ( $mask == 6 ) || ( $mask == '(xxx).xxx.xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '($1).$2.$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 6
    if ( ( $mask == 7 ) || ( $mask == '(xxx) xxx-xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '($1) $2-$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 7
    if ( ( $mask == 8 ) || ( $mask == '(xxx)-xxx-xxxx' ) ) {
    $phone = preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
    '($1)-$2-$3'." \n", $mynum);
    return $phone;
    } // end if $mask == 8
    return false; // Returns false if no conditions meet or input
    } // end function format_phone_number

    function validate_phone_number ( $phone ) {
    /*********************************************************************/
    /* Purpose: To determine if the passed string is a valid phone */
    /* number following one of the establish formatting */
    /* styles for phone numbers. This function also breaks */
    /* a valid number into it's respective components of: */
    /* 3-digit area code, */
    /* 3-digit exchange code, */
    /* 4-digit subscriber number */
    /* and validates the number against 10 digit US NANPA */
    /* guidelines. */
    /*********************************************************************/
    $format_pattern = '/^(?:(?:\((?=\d{3}\)))?(\d{3})(?:(?<=\(\d{3})\))'.
    '?[\s.\/-]?)?(\d{3})[\s\.\/-]?(\d{4})\s?(?:(?:(?:'.
    '(?:e|x|ex|ext)\.?\:?|extension\:?)\s?)(?=\d+)'.
    '(\d+))?$/';
    $nanpa_pattern = '/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?'.
    '[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9]'.
    '[0-9])|1212)))$/';

    // Init array of variables to false
    $valid = array('format' => false,
    'nanpa' => false,
    'ext' => false,
    'all' => false);

    //Check data against the format analyzer
    if ( preg_match ( $format_pattern, $phone, $matchset ) ) {
    $valid['format'] = true;
    }

    //If formatted properly, continue
    //if($valid['format']) {
    if ( !$valid['format'] ) {
    return false;
    } else {
    //Set array of new components
    $components = array ( 'ac' => $matchset[1], //area code
    'xc' => $matchset[2], //exchange code
    'sn' => $matchset[3] //subscriber number
    );
    // $components = array ( 'ac' => $matchset[1], //area code
    // 'xc' => $matchset[2], //exchange code
    // 'sn' => $matchset[3], //subscriber number
    // 'xn' => $matchset[4] //extension number
    // );

    //Set array of number variants
    $numbers = array ( 'original' => $matchset[0],
    'stripped' => substr(preg_replace('[\D]', '', $matchset[0]), 0, 10)
    );

    //Now let's check the first ten digits against NANPA standards
    if(preg_match($nanpa_pattern, $numbers['stripped'])) {
    $valid['nanpa'] = true;
    }

    //If the NANPA guidelines have been met, continue
    if ( $valid['nanpa'] ) {
    if ( !empty ( $components['xn'] ) ) {
    if ( preg_match ( '/^[\d]{1,6}$/', $components['xn'] ) ) {
    $valid['ext'] = true;
    } // end if if preg_match
    } else {
    $valid['ext'] = true;
    } // end if if !empty
    } // end if $valid nanpa

    //If the extension number is valid or non-existent, continue
    if ( $valid['ext'] ) {
    $valid['all'] = true;
    } // end if $valid ext
    } // end if $valid
    return $valid['all'];
    } // end functon validate_phone_number

    40 changes: 40 additions & 0 deletions z-alternative-regex.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    #0
    ^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$

    #1
    1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?
    '1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';

    print "match [$1-$2-$3]\n" if not defined $4;
    print "match [$1-$2-$3 $5]\n" if defined $4;

    #2
    /^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

    #3
    ^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

    #4
    ^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

    #5
    $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
    preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

    #6
    ^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$

    #7
    /\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/

    #8
    ^(\(?\d{3}\)?)([ .-])(\d{3})([ .-])(\d{4})$

    #9
    /\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/

    #10
    /\(([0-9]{3})\)([ .-]?)([0-9]{3})\2([0-9]{4})|([0-9]{3})([ .-]?)([0-9]{3})\5([0-9]{4})/

    #11
    ^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4}$