
|
View Full Version : php help on checking the value of the input field without symbols but period allowed?
sharmaine1111 09-24-2009, 11:25 AM I currently have a checking in my form input field that it should contain alphanumeric characters only, so not a single symbol is allowed However I want to revise it and disallow all symbols except period (.) how do i do that?
WebNaz 09-24-2009, 01:05 PM if ([^0-9a-zA-Z.], $string)
return false;
mattle 09-24-2009, 03:50 PM or if you're doing this server-side (which you should be), here's the PHP equivalent:
return !preg_match("/[^a-z\d\.\s]/i", $string);
What we're saying here is if we match a character that is in the character set ([]) of not (^) a letter (a-z), a digit (\d) or a period (\.)--note that just a (.) in your regex will match on any character!--or white-space (\s) performing a case-insensitive search (i), then return the Boolean opposite of our match result, ie return false if the string contains an illegal character, otherwise true.
You should also note that \w is a short hand for matching alpha-numeric characters, but it allows the underscore character in that set. If that's okay, you could get away with /[^\w\.\s]/.
sharmaine1111 09-25-2009, 10:51 AM what does \s mean? what does this mean: #[^a-z0-9\s-]#i such that: return !preg_match("#[^a-z0-9\s-]#i", $string) ?
bigfan 09-25-2009, 04:38 PM $allowed_symbols = array('.'); // Add more as needed.
if (!ctype_alnum(str_replace($allowed_symbols, '', $string)))
return false;
sharmaine1111 09-25-2009, 09:02 PM $allowed_symbols = array('.'); // Add more as needed.
if (!ctype_alnum(str_replace($allowed_symbols, '', $string)))
return false;
Doesn't this allow only period? how about entering alphanumeric? Curently I have this: #[^a-z0-9\s-]#i
bigfan 09-26-2009, 04:20 AM Doesn't this allow only period?It will allow both alphanumeric characters and periods, which is my understanding of what you want to do. If you try it you'll see.
function is_valid_string($string)
{
$allowed_symbols = array('.'); // Add more as needed.
return ctype_alnum(str_replace($allowed_symbols, '', $string));
}
// Test code:
foreach (array('good.string', 'bad*string') as $str) {
if (is_valid_string($str)) {
echo $str . ' -- valid<br />';
} else {
echo $str . ' -- not valid<br />';
}
}
// Result:
// good.string -- valid
// bad*string -- not valid
mattle 09-26-2009, 12:26 PM what does \s mean? what does this mean: #[^a-z0-9\s-]#i such that: return !preg_match("#[^a-z0-9\s-]#i", $string) ?
Sorry, I thought I explained that. The \s means that you are allowing white-space (spaces, tabs, etc.) There are basic components to this regex that I think need explaining...
[...] -- character set, regex will match if any character between the brackets matches
[^...] -- negated character set, regex will match if there is a character that is NOT within the braces, not to be confused with...
^[...] -- regex will match a string that BEGINS with that character set.
Now, within the character set, we have some ranges:
a-z -- match any lowercase* alphanumeric character
0-9 -- match any digit
And some specific allowable characters:
\s -- match any white-space
- -- match a hyphen (from your expression)
\. -- match a period (from the OP requirements)
Finally, we give a parameter to the expression (outside of the delimiters):
i -- perform a case-insensitive search. * This is why it's okay to match on just lowercase characters above.
A character set will match on any character in the brackets, therefore the expression
[a-z0-9\s\.-] will match any letter, number, space, hyphen or period in the expression.
Likewise, [^a-z0-9\s\.-] will match any character that is NOT a letter, number, space, hyphen or period.
That means that preg_match() on the expression above will return TRUE if there is a character that is not allowed. That alone is fine. If you functionalize the procedure to check for validity, you might have something like this:
if (hasIllegalChars($testVal))
{
//handle error
}
else
{
// value is safe
}
If, like me, it makes more logical sense to you to have your validation function return true if the string is safe, and false if it contains bad characters, you will have to find the logical opposite of preg_match(), by preceding it with !
if (isValid($testVal))
{
// value is safe
}
else
{
// handle error
}
I'm interested in the efficiency difference between my solution and bigfan's...
mattle 09-26-2009, 12:55 PM For those who are interested...
# cat timing.php
<?
$testStrings = array("A 28 character valid string.", "shrt_inv", "_inv at beginning",
"inv at end{", "a fairly long, and nonetheless, invalid string expression",
"a fairly long. and nonetheless. ..valid string expression");
$functions = array("regex", "ctype");
$results = array();
$executionCount = 10000;
foreach ($functions as $fn)
{
$results[$fn]['total'] = 0;
foreach ($testStrings as $str)
{
$start = microtime(true);
$result = NULL;
for ($i = 0; $i < $executionCount; ++$i)
{
$result = $fn($str);
}
$results[$fn][$str]['result'] = $result;
$results[$fn][$str]['ms'] = (microtime(true) - $start) * 1000;
$results[$fn]['total'] += $results[$fn][$str]['ms'];
}
}
print_r($results);
function regex($string)
{
return !preg_match("/[^a-z0-9\s\.-]/i", $string);
}
function ctype($string)
{
$allowed_symbols = array('.', '-', ' ');
return ctype_alnum(str_replace($allowed_symbols, '', $string));
}
?>
# php -f timing.php
Array
(
[regex] => Array
(
[total] => 398.58436584473
[A 28 character valid string.] => Array
(
[result] => 1
[ms] => 71.012020111084
)
[shrt_inv] => Array
(
[result] =>
[ms] => 59.103012084961
)
[_inv at beginning] => Array
(
[result] =>
[ms] => 56.730031967163
)
[inv at end{] => Array
(
[result] =>
[ms] => 62.520027160645
)
[a fairly long, and nonetheless, invalid string expression] => Array
(
[result] =>
[ms] => 64.160108566284
)
[a fairly long. and nonetheless. ..valid string expression] => Array
(
[result] => 1
[ms] => 85.05916595459
)
)
[ctype] => Array
(
[total] => 577.25596427917
[A 28 character valid string.] => Array
(
[result] => 1
[ms] => 96.320867538452
)
[shrt_inv] => Array
(
[result] =>
[ms] => 91.674089431763
)
[_inv at beginning] => Array
(
[result] =>
[ms] => 93.331098556519
)
[inv at end{] => Array
(
[result] =>
[ms] => 93.492984771729
)
[a fairly long, and nonetheless, invalid string expression] => Array
(
[result] =>
[ms] => 98.383903503418
)
[a fairly long. and nonetheless. ..valid string expression] => Array
(
[result] => 1
[ms] => 104.05302047729
)
)
)
bigfan 09-26-2009, 02:21 PM Impressive. Almost .000178 seconds difference per function call.
mattle 09-27-2009, 10:30 AM I think you got killed by the call to str_replace() :) I really wasn't trying to prove the validity of one solution over the other, I've just always been impressed by the efficiency of regular expressions. Back in my Perl days, we used to always time functions. Just curious how PHP regex's stacked up against the ctime functions.
I think there's a lot more information to be gleaned from this..for example, the ctime expression executed consistently on similar-length strings, regardless of where the offending character was, whereas the regular expression clearly operates faster if the illegal character is near the front.
I know a lot of people choose PHP because there's a lot of magic that happens without the programmer needing to do a lot of work--or understand what's going on internally. I, for one, am still interested in what's going on under the hood :)
bigfan 09-27-2009, 09:37 PM I know a lot of people choose PHP because there's a lot of magic that happens without the programmer needing to do a lot of work--or understand what's going on internally. I, for one, am still interested in what's going on under the hoodAh, now I see. Thank you for helping me, for one, to understand you better.
|