So I have a regex code to make sure the password is from 4 to 13 characters, it keeps failing
public function valid_password($password){
if(preg_match('^.{3,14}^', $password)){
return true;
}//end if
else{
return false;
}//end else
}
I'm using regex and not php's length attribute because I will be adding more regex code later on. However, now I'm stuck with this failing program.
The problem is, it makes sure the password is over 3 characters however it doesn't care how long it is as if I have set no limit.
Thanks in advance
You have used ^ as delimiters php.net/mregexp.reference.delimiters.php here:
^.{3,14}^
That's possible, but not a good idea in your case, because you need the ^ for its actual purpose. It matches the start of the subject normally. And to correctly count the length, yout need to do that. You also need the $ end of subject meta character.
So basically:
preg_match('/^.{3,14}$/'
Now if you want to combine this regex with other match criteria, I would recommend this fancy assertion syntax:
preg_match('/(?=^.{3,14}$) (...)/x', $password)
This will allow you to specify something else in place of ... - and keep the length check implicit.
^ is the anchor for the beginning of a string. The end of a string is delimited using $:
public function valid_password($password) {
return preg_match('~^.{3,14}$~', $password);
}
But in this case I wouldn't use a regex, but the strlen function instead:
public function valid_password($password) {
$length = strlen($password);
return $length >= 3 && $length <= 14;
}
If you like hacking around to save you that line:
public function valid_password($password) {
return isset($password[2]) && !isset($password[14]);
}
But really, why do you want to restrict password length to 14 characters? That way you prevent people from choosing really secure passwords. You probably should raise that limit.
Try this:
preg_match('/^.{3,14}$/', $password)
try
preg_match('/^.{3,14}$/', $password)
but regexp for counting string length?? = Overkill
^ matches the start of a string, not the end. $ matches the end.
And you forgot your delimiters.
The full, fixed line is:
if (preg_match('/^.{3,14}$/', $password)) {
However, I strongly recommend that you instead use:
$len = strlen($password);
if ($len >= 3 && $len <= 14) {
instead, since regular expressions are completely overkill for this.
Related
I had a discussion with my teacher about the mb_ functions. Whatever, one thing leading to another, we changed the subject and he gave me an example where strpos and strlen could be problematic, according to him:
$input = "something"; # input given by the user
$string = "hello"; # string to match
if ( strpos($input, $string) !== false && strlen($input) < strlen($string) ) {
echo "Correct input";
} else {
echo "Incorrect input";
}
(The question is not about how to match 2 strings)
According to my teacher, there may be a way to validate the statement and execute the code echo "Correct input";.
However, I can't see a flaw in this. Maybe there could be a problem with encoding? Do you have any idea?
okey i think that the flaw will be the if statement logic
how will you use strpos function which check the position of the first occurrence of a substring in a string , and in the same time you want to check if the input is greater than the subject ?
by logic it is impossible
I made this function to check if the first character is a letter.
function isLetter($string) {
return preg_match('/^\s*[a-z,A-Z]/', $string) > 0;
}
However, if I check a sentence that starts with a coma (,) the functions returns true. What is the proper regex to check if the first letter is a-z or A-Z?
You just need to remove the comma:
'/^\s*[a-zA-Z]/'
A slightly cleaner way, in my opinion. Just makes the code a little more human readable.
function isLetter($string) {
return preg_match('/^[a-z]/i', trim($string));
}
This question already has answers here:
php validate integer
(7 answers)
Closed 9 years ago.
Hey I'm trying to perform input validation in PHP to ensure that the stock values that are typed in are at least 1 positive integer and from 0-9. Should not contain any special characters.
For example, any of the following values should be valid:
7
0
32
47534
The following SHOULD NOT be valid:
asdf
35/gdf
../34.
etc..
I'm using the following if statement to check for the positive integer value of "$original_stock".
if (preg_match("/^[0-9]$/", $original_stock))
{
$error .="Original stock must be numerical.";
}
Additionally, I have a price field which should be validated as either an int or a double.
If there's an easier alternative to using regex, that's okay too!
Thanks in advance :)
Try this regexp:
/^\d+$/
The issue with your existing regexp is that it only matches strings with exactly one digit.
As for validating an int or a double:
/^\d+\.?\d*$/
Note that that regexp requires that there be at least one digit.
Use:
/^[0-9]+$/
The + means "one or more". Without it, your regex will only match a single digit. Or you could use the simpler variant:
/^\d+$/
For floats, try something like:
/^\d+(\.\d{1,2})?/
This will match one or more digits, optionally followed by a . and one or two digits. (i.e. .12 will not match.)
To save yourself some headaches, you can also use the is_int and is_float functions.
Lastly; note that your check is wrong. preg_match will return 0 if it fails, so you should write it as:
if (!preg_match("/^\+$/", $original_stock)) {
// error
}
(note the !).
You may want to use the
is_int
Don't reinvent a wheel slower than an existing one, use a motorcycle: is_int.
#Assuming $original_stock is a single value...
if (is_int($original_stock)) {
#Valid, do stuff
}
else {
#Invalid, do stuff
}
#Assuming $original_stock is an array...
$valid = true;
foreach ($original_stock as $s) {
if (!is_int($s)) {
$valid = false;
break;
}
}
if ($valid) {...}
else {...}
I just ran into this exact problem and solved it this way using the regex.
I think the problem is your caret ^.
/^[0-9]$/
I moved it inside the class and got the results I needed.
function validate_int($subject)
{
//Pattern is numbers
//if it matches anything but numbers, we want a fail
$pattern = '/[^0-9]/';
$matches = preg_match($pattern, $subject);
if($matches > 0)
return false;
else
return true;
}
I am trying to validate a Youtube URL using regex:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+~', $videoLink)
It kind of works, but it can match URL's that are malformed. For example, this will match ok:
http://www.youtube.com/watch?v=Zu4WXiPRek
But so will this:
http://www.youtube.com/watch?v=Zu4WX£&P!ek
And this wont:
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
I think it's because of the + operator. It's matching what seems to be the first character after v=, when it needs to try and match everything behind v= with [a-zA-Z0-9-]. Any help is appreciated, thanks.
To provide an alternative that is larger and much less elegant than a regex, but works with PHP's native URL parsing functions so it might be a bit more reliable in the long run:
$url = "http://www.youtube.com/watch?v=Zu4WXiPRek";
$query_string = parse_url($url, PHP_URL_QUERY); // v=Zu4WXiPRek
$query_string_parsed = array();
parse_str($query_string, $query_string_parsed); // an array with all GET params
echo($query_string_parsed["v"]); // Will output Zu4WXiPRek that you can then
// validate for [a-zA-Z0-9] using a regex
The problem is that you are not requiring any particular number of characters in the v= part of the URL. So, for instance, checking
http://www.youtube.com/watch?v=Zu4WX£&P!ek
will match
http://www.youtube.com/watch?v=Zu4WX
and therefore return true. You need to either specify the number of characters you need in the v= part:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]{10}~', $videoLink)
or specify that the group [a-zA-Z0-9-] must be the last part of the string:
preg_match('~http://youtube.com/watch\?v=[a-zA-Z0-9-]+$~', $videoLink)
Your other example
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
does not match, because the + sign requires that at least one character must match [a-zA-Z0-9-].
Short answer:
preg_match('%(http://www.youtube.com/watch\?v=(?:[a-zA-Z0-9-])+)(?:[&"\'\s])%', $videoLink)
There are a few assumptions made here, so let me explain:
I added a capturing group ( ... ) around the entire http://www.youtube.com/watch?v=blah part of the link, so that we can say "I want get the whole validated link up to and including the ?v=movieHash"
I added the non-capturing group (?: ... ) around your character set [a-zA-Z0-9-] and left the + sign outside of that. This will allow us to match all allowable characters up to a certain point.
Most importantly, you need to tell it how you expect your link to terminate. I'm taking a guess for you with (?:[&"\'\s])
?) Will it be in html format (e.g. anchor tag) ? If so, the link in href will obviously end with a " or '.
?) Or maybe there's more to the query string, so there would be an & after the value of v.
?) Maybe there's a space or line break after the end of the link \s.
The important piece is that you can get much more accurate results if you know what's surrounding what you are searching for, as is the case with many regular expressions.
This non-capturing group (in which I'm making assumptions for you) will take a stab at finding and ignoring all the extra junk after what you care about (the ?v=awesomeMovieHash).
Results:
http://www.youtube.com/watch?v=Zu4WXiPRek
- Group 1 contains the http://www.youtube.com/watch?v=Zu4WXiPRek
http://www.youtube.com/watch?v=Zu4WX&a=b
- Group 1 contains http://www.youtube.com/watch?v=Zu4WX
http://www.youtube.com/watch?v=!Zu4WX£&P4ek
- No match
a href="http://www.youtube.com/watch?v=Zu4WX&size=large"
- Group 1 contains http://www.youtube.com/watch?v=Zu4WX
http://www.youtube.com/watch?v=Zu4WX£&P!ek
- No match
The "v=..." blob is not guaranteed to be the first parameter in the query part of the URL. I'd recommend using PHP's parse_url() function to break the URL into its component parts. You can also reassemble a pristine URL if someone began the string with "https://" or simply used "youtube.com" instead of "www.youtube.com", etc.
function get_youtube_vidid ($url) {
$vidid = false;
$valid_schemes = array ('http', 'https');
$valid_hosts = array ('www.youtube.com', 'youtube.com');
$valid_paths = array ('/watch');
$bits = parse_url ($url);
if (! is_array ($bits)) {
return false;
}
if (! (array_key_exists ('scheme', $bits)
and array_key_exists ('host', $bits)
and array_key_exists ('path', $bits)
and array_key_exists ('query', $bits))) {
return false;
}
if (! in_array ($bits['scheme'], $valid_schemes)) {
return false;
}
if (! in_array ($bits['host'], $valid_hosts)) {
return false;
}
if (! in_array ($bits['path'], $valid_paths)) {
return false;
}
$querypairs = explode ('&', $bits['query']);
if (count ($querypairs) < 1) {
return false;
}
foreach ($querypairs as $querypair) {
list ($key, $value) = explode ('=', $querypair);
if ($key == 'v') {
if (preg_match ('/^[a-zA-Z0-9\-_]+$/', $value)) {
# Set the return value
$vidid = $value;
}
}
}
return $vidid;
}
Following regex will match any youtube link:
$pattern='#(((http(s)?://(www\.)?)|(www\.)|\s)(youtu\.be|youtube\.com)/(embed/|v/|watch(\?v=|\?.+&v=|/))?([a-zA-Z0-9._\/~#&=;%+?-\!]+))#si';
preg_match_all("/[^A-Za-z0-9]/",$new_password,$out);
The above only checks the 1st character, how to check whether all are alpha-numeric?
It's probably a better idea to use the builtin functions: ctype_alnum
preg_match("/^[A-Za-z0-9]*$/", $new_password);
This gives true if all characters are alphanumeric (but beware of non-english characters). ^ marks the start of the string, and ^$^ marks the end. It also gives true if the string is empty. If you require that the string not be empty, you can use the + quantifier instead of *:
preg_match("/^[A-Za-z0-9]+$/", $new_password);
Old question, but this is my solution:
<?php
public function alphanum($string){
if(function_exists('ctype_alnum')){
$return = ctype_alnum($string);
}else{
$return = preg_match('/^[a-z0-9]+$/i', $string) > 0;
}
return $return;
}
?>