skij
asked on
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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');
@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:
https://www.experts-exchange.com/questions/28719388/PHP-Test-if-string-contains-only-numbers-dashes-parentheses-and-spaces.html?anchorAnswerId=40990071#a40990071
https://www.experts-exchange.com/questions/28719388/PHP-Test-if-string-contains-only-numbers-dashes-parentheses-and-spaces.html?anchorAnswerId=40990071#a40990071
ASKER
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.
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.
http://iconoun.com/demo/temp_skij.php
Open in new window