So I thought I had this right?
if(!preg_match('^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+.{7,}$', $passOne)) {
$msg = "Password does not contain at least 1 number/letter, 8 character minimum requirement.";
}
I test it over at https://regex101.com/ and put ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+.{7,}$ to work and things like RubyGlue12 pass and is a match and other things that aren't.
But no matter what, I cannot make any match in the actual PHP code. Even if the POST is a variable manually.
edit: $_POST['password'] is $passOne
Help?
You have .+.{7,} that does not make much sense since it means match any characters 1 or more times, and then any characters 7 or more times.
1 letter, 1 digit and min 8 characters regex will look like
(?i)^(?=.*[a-z])(?=.*\d).{8,}$
Regex explanation:
(?i) - Turning case sensitivity off (unless you need to check for 1 uppercase and 1 lowercase letters - then, remove the i flag and replace (?=.*[a-z]) with (?=.*[a-z])(?=.*[A-Z]))
^ - Start of string
(?=.*[a-z]) - Positive look-ahead requirement to have at least 1 letter
(?=.*\d) - Positive look-ahead requirement to have at least 1 digit
.{8,} - At least 8 characters
$ - End of string.
And PHP code is:
$re = "/^(?=.*[a-z])(?=.*\\d).{8,}$/i";
$passOne = "RubyGlue12";
//$passOne = "eee"; // uncomment to echo the error message
if(!preg_match($re, $passOne)) {
echo "Password does not contain at least 1 number/letter, 8 character minimum requirement.";
}
And yes, with preg_match function, you must use some regex delimiters. I am using / here.
Here's a regex that tests for what the password should not be, instead of what it should be.
/^(.{0,7}|[^a-z]*|[^\d]*)$/i
Example:
if (preg_match('/^(.{0,7}|[^a-z]*|[^\d]*)$/i', $passOne)) {
echo "Validation failed.\n";
}
Explanation:
There are essentially 3 separate tests within the regex (each separated by a |, and each are case-insensitive due to the i option at the end). If it passes any of the tests, then the entire validation fails.
Test 1: Does the entire string only contain 0-7 characters? Fail.
Test 2: Does the entire string contain no alpha characters? Fail.
Test 3: Does the entire string contain no digits? Fail.
Related
My regex validation is producing true when it should be false. I've tried this exact example using online regex validators, and it is always rejected except in my code. Am I doing something wrong?
$name = "1NTH";
preg_match("/[A-Z][A-Z][A-Z][A-Z]?/",$name);
This exact example is evaluating to true.
You're getting the correct behaviour, as you're asking for three capital letters eventually followed by a fourth one.
You probably want to use this regex:
/^[A-Z][A-Z][A-Z][A-Z]?$/
(note the ^, start of line, and $ end of line) as it explicitly requires that the capital letters must be all the content of the text line.
This is because it is true. It contains [A-Z] characters.
You're missing the anchors to start your regex from the start of the string to finish of the string.
^[A-Z][A-Z][A-Z][A-Z]?$
There's nothing wrong with your regex. It is valid based on the rule you specified.
Let's do it one step at a time:
[A-Z] means match exactly 1 upper case alphabet.
[A-Z]? means, match either 0 or 1 upper case alphabet.
See what's going on? If not, move on.
[A-Z][A-Z][A-Z] means match exactly 3 upper case alphabets. (1 for each [A-Z] rule)
[A-Z][A-Z][A-Z][A-Z]? means the first three characters must be an upper case alphabet. The last one can either be 0 or 1 upper case alphabet.
In your example, 1NTH contains exactly 3 upper case alphabets, which is correct. You didn't put any restrictions on whether it should contain number or not, whether before or after the 3 alphabets. And the last [A-Z]?? Well, that's optional, right? (see rule #2)
The standard PHP regular expression engine checks if the the string contains the pattern, and is not an exact match. That differs to, for example, the standard Java regular expression engine.
You should use ^ and $, which match respectively the beginning and the end of a string. Both are zero-length assertions.
$name = "1NTH";
preg_match("/^[A-Z]{3}[A-Z]?$/", $name);
PS: I have optimized your regular expression by using the quantifier {3}, which matches three subsequent occurrences of the preceding character or group.
Accoring to PHP Manual:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
In your example, there must be 3 obligatory and 1 optional capital letter. So, the match is due.
As stribizhev said, your regex matches since you're asking for more than 3 letters which are found in $name. I assume you want to reject "1NTH" because it starts with a digit. That means you have to add an anchor saying "from the start" (\A).
Also, the 3 repeated [A-Z] can be summarized by adding a repeat-counter. So the whole statement should be: \A[A-Z]{3,}
You have given like this,
$name = "1NTH";
preg_match("/[A-Z][A-Z][A-Z][A-Z]?/",$name);
In your code some please change this below code
$name = "1NTH";
preg_match("/[A-Z][A-Z][A-Z][A-Z]?$/",$name);
you have missed '$' in end of preg string.
i have checked and it's working perfectly to your requirement.
See this link,and you also test once in this link. Click Here
I need some help with a regex. I'm terrible at this.
Rules:
Only letters a through z and spaces
Minimum 2 letters
Maximum 30 letters
Each word must be at least 2 letters
Only the first letter of each word may be capital but the first letter must always be capital
My attempt:
^[A-Z][a-z]{2,30}$
I'm using this in PHP.
Okay, so let's try solving requirements 1 to 3 first. If you mean 2 to 30 characters it's as simple as this:
^[a-zA-Z ]{2,30}$
Now for the other requirements. Let's handle those alone. Point 4 requires each word to be of the form [a-zA-Z][a-z]*. To make sure that each word has at least two letters, we can simply turn the * into a + (which means 1 or more repetitions). If we insert explicit spaces around these, that makes sure that the [a-z]+ cannot be followed directly by a capital letter:
^[A-Z][a-z]+(?:[ ]+[a-zA-Z][a-z]+)*$
Note that I treated the first word separately.
Finally, how do we combine the two? By putting one into a lookahead. I'm going for the counting here:
^(?=[a-zA-Z ]{2,30}$)[A-Z][a-z]+(?:[ ]+[a-zA-Z][a-z]+)*$
This works because, after the input is checked against the lookahead the engine resets it "cursor" to where it started (the beginning of the string) and continues matching as usual. This way we can run two passes over the input, checking for independent conditions.
Finally, note that the lookahead requirement simply translates to the string's length. In such a case it would be easier (and most often better) to check this separately:
$len = strlen($input)
if ($len < 2 || $len > 30)
// report error about string length
else if (!preg_match('/^[A-Z][a-z]+(?:[ ]+[a-zA-Z][a-z]+)*$/', $input))
// report error about pattern
else
// process input
This makes it much easier to give sensible error messages depending on which condition was violated.
Let's try this:
^[A-Z]((?<= )[A-Z]|[a-z ]){2,29}$
[A-Z] -- a capital letter
(
(?<= )[A-Z] -- either a capital letter preceded by a space
| -- or
[a-z ] -- a lowercase letter or a space
){2,29} -- 2 to 29 times (plus the initial capital)
You will need to use the PCRE (not ereg_*) for the lookbehind to work.
"My name Is bob"
↑ ↑ ↑
| | \-- this is a "(?<= )[A-Z]"
| \--- this is a "[a-z]"
\---- this is a "[ ]"
"naMe"
↑
\-- this is NOT a "(?<= )[A-Z]" (a character before the [A-Z] is not a space)
EDIT: damn, you added the "Each word must be at least 2 letters". Use m.buettner's.
This question already has answers here:
Regular expression to enforce complex passwords, matching 3 out of 4 rules
(4 answers)
Closed 9 years ago.
Sorry to all if this code is poor as I am just following through a book to and modifying it for my school project as I just started php less than a month ago.
I am trying to understand what this validation mean but can't seem to comprehend it full as I am new with php.
Code:
if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass']) ) {
//$p = mysqli_real_escape_string ($dbc, $_POST['pass']);
$p = $_POST['pass'];
$sticky_password = $p;
} else {
$error['pass'] = 'Please enter a valid password!';
}
Any help would be really appreciated! Thanks!
Thank you very much.. :)
We have the following regex:
/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/
The first and last / are the delimiters.
^ -> The start, $ -> The end
Which means if input is abc and your regex is /^bc$/, it won't get matched since bc is not at the beginning.
Now we have (\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}
The {6,20} is the quantifier part, which means 6 up to 20 times.
Let's break the regex further: \w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*
Let's provide some equivalents:
\w => [a-zA-Z0-9_]
\d => [0-9]
* => zero or more times
(?=) Is a lookahead assertion. Example /a(?=b)/ this will match any "a" followed by "b"
The purpose of those lookaheads:
(?=\w*\d) => check if there is a digit
(?=\w*[a-z]) => check if there is a lowercase letter
(?=\w*[A-Z]) => check if there is a uppercase letter
Let's take (?=\w*\d): The \w* is just there as a "workaround" in case there is [a-zA-Z0-9_]* before a digit
In the end, this regex just makes sure that the input:
is 6 to 20 characters long
that there is minimal: 1 lowercase, 1 uppercase and 1 digit
that the allowed characters are letters (upper and lowercase (a-z,A-Z)), digits and underscore.
Three interesting sites www.regexper.com, www.regular-expressions.info and www.regex101.com.
Note: Don't restrict passwords, you have to hash them anyway. Take a look here or check the other questions on SO.
Actually this pattern matches all passwords with at least 3 characters (a digit, an upper case and a lower case in any order) without a length limit (except for the regex engine). All characters must be word characters (ie: from the class \w).
The author intention was probably to match all passwords between 6 and 20 word characters with at least one digit, one upper case and one lower case, as the quantifier and the lookaheads suggest.
In short this pattern is wrong, but probably aims what this classical password validation pattern does:
^(?=\w*[A-Z])(?=\w*[a-z])(?=\w*\d)\w{6,20}$
or this one without all redundant \w:
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)\w{6,20}$
Explanation: lookaheads are zero-width assertions, they don't consume characters, they are only tests. Consequence each of them are performed from the start of the string since they are anchored to the ^. If each lookahead succeeds, then \w{6,20} is tested always from the start of the string to know if it contains only between 6 and 20 word characters. $ means the end of the string.
As said in comments, this pattern comes from the book "Effortless E-commerce" first edition, by Larry Ullman.
Even if the author wrotes:
"And, admittedly, even I often have to look up the proper syntax for patterns, but this one requires a high level of regular expression expertise."
and even if I disagree with the second part of the sentence, I think this pattern is a simple typo. However I don't know if this one has been corrected in the second edition.
I found lots of php regex and other options to determine string length, and if it contains one letter or one number, but how do I determine if a string has 2 numbers in it?
I am trying to validate a password that
Must have exactly 8 characters
One of them must be an Uppercase letter
2 of them must be numbers
Is there a one line regex solution for this?
if (preg_match(
'/^ # Start of string
(?=.*\p{Lu}) # at least one uppercase letter
(?=.*\d.*\d) # at least two digits
.{8} # exactly 8 characters
$ # End of string
/xu',
$subject)) {
# Successful match
(?=...) is a lookahead assertion. It checks if a certain regex can be matched at the current position, but doesn't actually consume any part of the string, so you can just place several of those in a row.
I need to check if string has anything else than what specified below
it must begins from letter (either uppercase or lowercase)
can have alphabetical characters
can have numeric characters
can have dashes
can have minus sign -
can have underscore _
can have comas ,
can have dots .
length from 4 to 35 caracters no more no less
everything else should not be in this string have have
i am stuck on this:
preg_match('/^[\w]{4,35}$/i', $username)
if( !preg_match('/^[a-zA-Z][a-zA-Z0-9_,.-]*$/', $username ))
echo "failed\n";
preg_match('/^[\w]{4,35}$/i', $username)
OK lets see what this doesn't work :
Match the beginning of the string, followed by [a-zA-Z0-9_] at least 4 times with a maximum of 35 times. This is quite different from your requirements.
Instead what you should use :
/^[a-zA-Z][-,.\w]{3,34}$/
The case sensitivity i modifier is not needed. Also I don't think this is exactly what you want. Usually you would need to specify a minimum length which you don't. This can match "a" for example (not a good username)