PHP: Test if string contains only numbers, dashes, parentheses and spaces

Using PHP, how cant I test if string contains only numbers, dashes, parentheses and spaces? If it contains anything else, like a letter, it should return false.
LVL 10
skijAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dave BaldwinFixer of ProblemsCommented:
'preg_match' is probably what you want.  The difficulty is constructing the matching instruction for what you want.

http://php.net/manual/en/function.preg-match.php

This seems to work.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>Preg_match</title>
</head>
<body>

<?php
$str1 = "This is all alpha.";
$str2 = "1234567890-() ";
// The "i" after the pattern delimiter indicates a case-insensitive search
if (preg_match("/[^0-9-() ]/", $str2)) {
    echo "A match was found.";
} else {
    echo "A match was not found.";
}
?>

</body>
</html>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
Here is a way to annotate the solution with comments and show how to test it.
http://iconoun.com/demo/temp_skij.php
<?php // demo/temp_skij.php

/**
 * http://www.experts-exchange.com/questions/28719388/PHP-Test-if-string-contains-only-numbers-dashes-parentheses-and-spaces.html
 *
 * http://php.net/manual/en/function.preg-match.php
 */
error_reporting(E_ALL);
echo '<pre>';

// A FILTER FUNCTION
function skij_filter($str)
{
    // A REGEX FOR THE EXPECTED FILTERS
    $rgx
    = '/'     // REGEX DELIMITER
    . '['     // START OF CHARACTER CLASS
    . '^'     // NEGATION - MATCH NONE OF THESE
    . '0-9'   // RANGE OF NUMBERS
    . '-'     // THE DASH
    . '()'    // THE PARENTHESES
    . ' '     // THE BLANK
    . ']'     // ENDOF CHARACTER CLASS
    . '/'     // REGEX DELIMITER
    ;
    // TEST FOR A NEGATIVE OF A NEGATIVE CONDITION (!)
    if (!preg_match($rgx, $str)) return TRUE;
    return FALSE;
}

// MAYBE A TELEPHONE NUMBER?  SOME TEST CASES
$tests =
[ '123'
, '(301) 555-1212'
, 'crump'
, '11111111111111111111111111111111111111111111111111111'
, '999-999-9999'
, '((((((((((((((()'
, '--------------'
, '-99993'
, '1-800-BIG-DOGS'
]
;

// RUN THE TESTS AND SHOW THE RESULTS
foreach ($tests as $str)
{
    echo PHP_EOL;
    if ( skij_filter($str) )
    {
        echo ' OK: ';
    }
    else
    {
        echo 'NOK: ';
    }
    echo $str;
}

Open in new window

0
Ray PaseurCommented:
On the chance that you're looking for phone number authentication, there is a well-understood design pattern ;-)
<?php // demo/validate_phone_numbers.php

/**
 * A function to validate a USA phone number and return a normalized string
 *
 * MAN PAGE: http://discuss.fogcreek.com/joelonsoftware3/default.asp?cmd=show&ixPost=102667&ixReplies=15
 * MAN PAGE: http://www.nanpa.com/number_resource_info/index.html
 */
error_reporting(E_ALL);


function strtophone($phone, $format=FALSE, $letters=FALSE, $dlm='-')
{
    if ($letters)
    {
        // TURN INPUT LIKE 1-800-BIG-DOGS
        // INTO INPUT LIKE 1-800-244-3647
        $phone = strtoupper($phone);
        if (preg_match('/[A-Z]/', $phone))
        {
            $phone = strtr
            ( $phone
            , 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
            , '22233344455566677778889999'
            )
            ;
        }
    }

    // DISCARD NON-NUMERIC CHARACTERS
    $phone = preg_replace('/[^0-9]/', NULL, $phone);

    // DISCARD A LEADING '1' FROM NUMBERS ENTERED LIKE 1-800-555-1212
    if (substr($phone,0,1) == '1') $phone = substr($phone,1);

    // IF LESS THAN TEN DIGITS, IT IS INVALID
    if (strlen($phone) < 10) return FALSE;

    // IF IT STARTS WITH '0' OR '1' IT IS INVALID, SECOND DIGIT CANNOT BE '9' (YET)
    if (substr($phone,0,1) == '0') return FALSE;
    if (substr($phone,0,1) == '1') return FALSE;
    if (substr($phone,1,1) == '9') return FALSE;

    // ISOLATE THE COMPONENTS OF THE PHONE NUMBER
    $ac = substr($phone,0,3); // AREA
    $ex = substr($phone,3,3); // EXCHANGE
    $nm = substr($phone,6,4); // NUMBER
    $xt = substr($phone,10);  // EXTENSION

    // ADD OTHER TESTS HERE AS MAY BE NEEDED - THESE ARE FOR LOCAL APPS
    if ($ac == '900') return FALSE;
    if ($ac == '976') return FALSE;
    if ($ex == '555') return FALSE;

    // IF NOT FORMATTED
    if (!$format) return $phone;

    // STANDARDIZE THE PRINTABLE FORMAT OF THE PHONE NUMBER LIKE 212-555-1212-1234
    $formatted_phone = $ac . $dlm . $ex . $dlm . $nm;
    if ($xt != '') $formatted_phone .= $dlm . $xt;
    return $formatted_phone;
}



// DEMONSTRATION OF THE FUNCTION IN ACTION.
if (!empty($_GET["p"]))
{
    // VALIDATE PHONE USING FUNCTION ABOVE
    if (!$phone = strtophone($_GET["p"], TRUE))
    {
        // FUNCTION RETURNS FALSE IF PHONE NUMBER IS UNUSABLE
        echo "BOGUS: {$_GET["p"]} ";
    }
    else
    {
        // SHOW THE FORMATTED PHONE
        echo "VALID: {$_GET["p"]} == $phone";
    }
}


// PUT UP A FORM TO TEST PHONE NUMBERS
function ph($p)
{
    echo "<br/><a href=\"{$_SERVER['PHP_SELF']}?p=" . urlencode($p) . "\">$p</a>" . PHP_EOL;
}

$form = <<<EOD
<form>
ENTER A PHONE NUMBER:
<input name="p" /><br/>
<input type="submit" />
</form>
TRY SOME OF THESE (CLICK OR COPY AND PASTE):
EOD;

echo $form;

ph('1-800-5551212');
ph('202-537-7560');
ph('202 537 7560');
ph('1-202-537-7560');
ph('(202) 537-7560');
ph('1.202.537.7560');
ph('123456789');
ph('703-356-5300 x2048');
ph('(212) 555-1212');
ph('1 + (212) 555-1212');
ph('1 (292) 226-7000');

Open in new window

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Ray PaseurCommented:
@skij (and anyone else coming across this question in the future): It is usually a good idea to test the solutions before accepting them.  In the instant case, the accepted solution will pass both $str1 and $str2.  The correct solution was available here:
http://www.experts-exchange.com/questions/28719388/PHP-Test-if-string-contains-only-numbers-dashes-parentheses-and-spaces.html#a40990071
0
skijAuthor Commented:
Ray, thanks for your comments.  I solution I accepted provided a working regular expression that met the needs of my original post.  I tested the regular expression and it met my needs, which is why I accepted it as the solution.
0
Dave BaldwinFixer of ProblemsCommented:
Ray, I did check my code before I posted it.  I didn't put it in a loop like you did but it shows the correct results if you manually change the variable in the 'preg_match' line.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.