Require both letters and numbers - regExp - javascript

I am trying to figure how to require both letters and numbers only without any other characters. So literally [a-z] and ( \d or [0-9] ) depending what is better way of doing it for numbers.
So if I had a string that requires validation:
$toValidate = 'Q23AS9D0APQQ2'; // It may start with letter or number, both cases possible.
And then if I had validation for it:
return /([a-z].*[0-9])|([0-9].*[a-z])/i.test($toValidate);
I used an i flag here because it could be that user enters it lowercase or uppercase, it's user preference... So that regex fails... It accepts special characters also, so that is not desired effect.
With the validation above, this passes as well:
$toValidate = 'asdas12312...1231#asda___213-1';
Then I tried something crazy and I don't even know what I have done, so if anyone could tell me beside the correct answer, I'll truly appreciate.
return /([a-z].*\d)+$|(\d.*[a-z])+$/i.test($toValidate);
This seemed to work great. But then when I tried to continue typing letters or numbers after an special character it still validates as true.
Example:
$toValidate = 'q2IasK231#!#!#_+123';
So please help me understand regularExpressions better and tell me what is the way to validate the string at the beginning of my question. Letters and numbers expected in the string.

To allow only letters and digits with at least one letter and at least one digit use:
/^(?=.*?\d)(?=.*?[a-zA-Z])[a-zA-Z\d]+$/
Regex breakdown:
^ # start of input
(?=.*?\d) # lookahead to make sure at least one digit is there
(?=.*?[a-zA-Z]) # lookahead to make sure at least one letter is there
[a-zA-Z\d]+ # regex to match 1 or more of digit or letters
$ # end of input
RegEx Demo
You should not use .* in your regex otherwise it will allow any character in the input.

what you are looking for in pseudo is:
START-ANCOR [a-zA-Z0-9] 0->Inf times , ([a-zA-Z][0-9] OR [0-9][a-zA-Z]), [a-zA-Z0-9] 0->Inf times END-ANCOR
in words, start with anything from your lang, end with anything from your lang and contain a seam between letters and digits or the other way around
Should be like this:
/^([a-z0-9]* (([a-z][0-9]) | ([0-9][a-z])) [a-z0-9]*)$/i.

You can combine more than one type of character within the brackets. So, the following regex should work:
/^([a-z0-9]+)$/i.
The ^ and $ match the start and end of the string, so the whole string will be tested for the conditions. The [a-z0-9] makes it match only letters and numbers. The + makes it match one or more character. And the "i" at the end, as you know, makes it case insensitive.

Related

Regex - how to ignore order of the matched groups? [duplicate]

This question already has answers here:
Password REGEX with min 6 chars, at least one letter and one number and may contain special characters
(10 answers)
Closed 2 years ago.
I'm trying to create a regex validation for a password which is meant to be:
6+ characters long
Has at least one a-z
Has at least one A-Z
Has at leat one 0-9
So, in other words, the match will have :
at least one a-z, A-Z, 0-9
at least 3 any other characters
I've came up with:
((.*){3,}[a-z]{1,}[A-Z]{1,}[0-9]{1,})
it seems pretty simple and logical to me, but 2 things go wrong:
quantifier {3,} for (.*) somehow doesn't work and destroys whole regex. At first I had {6,} at the end but then regex would affect the quantifiers in inner groups, so it will require [A-Z]{6,} instead of [A-Z]{1,}
when I remove {3,} the regex works, but will match only if the groups are in order - so that it will match aaBB11, but not BBaa11
This is a use case where I wouldn't use a single regular expression, but multiple simpler ones.
Still, to answer your question: If you only want to validate that the password matches those criteria, you could use lookaheads:
^(?=.{6})(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9])
You're basically looking for a position from which you look at
6 characters (and maybe more to follow, doesn't matter): (?=.{6})
maybe something, then a lowercase letter: (?=.*?[a-z])
maybe something, then an uppercase letter: (?=.*?[A-Z])
maybe something, then a digit: (?=.*?[0-9])
The order of appearance is arbitrary due to the maybe something parts.
(Note that I've interpreted 6 characters long as at least 6 characters long.)
I believe this is what you want:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[!-~]{6,}$
If we follow your spec to the letter, your validation password looks like this:
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}$
However, we need to improve on this, because apart from the number, lower-case and upper-case letter, are you really willing to accept any character? For instance, can the user use a character in the Thai language? A space character? A tab? Didn't think so. :)
If you want to allow all the printable ASCII characters apart from space, instead of a dot, we can use this character range: [!-~]
How does it work?
The ^ anchor makes sure we start the match at the start of the string
The (?=.*[a-z]) lookahead ensures we have a lower-case character
The (?=.*[A-Z]) lookahead ensures we have an upper-case character
The (?=.*[0-9]) lookahead ensures we a digit
The (?=.*[a-z]) lookahead ensures we have a lower-case character
The [!-~]{6,} matches six or more ASCII printable ASCII characters that are not space.
The $ ensures we have reached the end of the string (otherwise, the password could contain more characters that are not allowed).
you could use this pattern ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,}

javascript regex validation issue

I am writing a javascript regex for the following:
must have at least one digit
must have at least one capital letter
must be between 8-15 characters
I have tried it like this:
function isStrongPassword(strInput) {
//works well except A1aaaaaa
var regex = /^(?=.*\d)(^[A-Za-z0-9])(?=.*[A-Z]).{7,14}$/;
return regex.test(strInput);
}
This is working properly, except the fact it is not matching with A1aaaaaa, which is a valid input.
Any help is appreciated.
Your expression fails because of (?=.*[A-Z]). None of the characters following the first one is upper case.
It seems this expression should suffice:
^(?=[^\d]*\d)(?=[^A-Z]*[A-Z]).{8,15}$
Note that switching .* to [^...]* has nothing to do with your problem, but it avoids backtracking. Alternatively you could use lazy matching: .*?.
Your regex was breaking because of the (^[A-Za-z0-9]) part, which would mean that after a digit, there must be a letter or digit, and then a capital letter. This should work
/^(?=.*\d)(?=.*[A-Z]).{8,15}$/;
Which breaks down like this...
/
^ # start match
(?=.*\d) # is there a digit up ahead (maybe after zero or more anythings)
(?=.*[A-Z]) # is there a capital up ahead (maybe after zero or more anythings)
.{8,15} # 8 to 15 anythings
$ # end match
/

Javascript Regex Pattern

I'm trying to create a regex pattern that allows the user to create a username with the following specifications. (For the purposes of this initial pattern, I'm only using standard american English alphabet.
The first character must be an alphabetic letter (uppercase or lowercase). [a-zA-Z]
The last character must be a alphanumeric (uppercase or lowercase). [a-zA-Z0-9]
Any characters in between must be letters or numbers with one rule:
The user can use a period(.), dash(-), or underscore(_) but it must be followed by an alphanumeric character. So no repeats of one or more of these characters at a time.
I've tried the following regex pattern but am not getting the results I was hoping for. Thanks for taking the time to help me on this.
^[a-zA-Z]([a-zA-Z0-9]+[._-]?[a-zA-Z0-9]+)+$
EDIT
It might actually be working the way I expected. But I'm always getting two matches returned to me. The first one being the entire valid string, the second being a shortened version of the first string usually chopping off the first couple of characters.
Examples of valid inputs:
Spidy
Spidy.Man
Ama-za-zing_Spidy
Examples of invalid inputs:
Extreme___Spidy (repeated underscores)
The_-_Spidy (repeated special characters)
_ _ SPIDY _ _ (starts and ends with special characters)
Sounds like this pattern:
^[a-zA-Z]([._-]?[a-zA-Z0-9])*$
^[a-zA-Z]([._-]?[a-zA-Z0-9]+)*$

Please explain some Javascript Regular Expressions

I'm learning Javascript via an online tutorial, but nowhere on that website or any other I googled for was the jumble of symbols explained that makes up a regular expression.
Check if all numbers: /^[0-9]+$/
Check if all letters: /^[a-zA-Z]+$/
And the hardest one:
Validate Email: /^[\w-.+]+\#[a-zA-Z0-9.-]+.[a-zA-z0-9]{2,4}$/
What do all the slashes and dollar signs and brackets mean? Please explain.
(By the way, what languages are required to create a flexible website? I know a bit of Javascript and wanna learn jQuery and PHP. Anything else needed?)
Thanks.
There are already a number of good sites that explain regular expressions so I'll just dive a bit into how each of the specific examples you gave translate.
Check if all numbers: ^ anchors the start of the expression (e.g. start at the beginning of the text). Without it a match could be found anywhere. [0-9] finds the characters in that character class (e.g. the numbers 0-9). The + after the character class just means "one or more". The ending $ anchors the end of the text (e.g. the match should run to the end of the input). So if you put that together, that regular expression would allow for only 1 or more numbers in a string. Note that the anchors are important as without them it might match something like "foo123bar".
Check if all letters: Pretty much the same as above but the character classes are different. In this example the character class [a-zA-Z] represents all lowercase and uppercase characters.
The last one actually isn't any more difficult than the other two it's just longer. This answer is getting quite long so I'll just explain the new symbols. A \w in a character class will match word characters (which are defined per regex implementation but are generally 0-9a-zA-Z_ at least). The backslash before the # escapes the # so that it isn't seen as a token in the regex. A period will match any character so .+ will match one or more of any character (e.g. a, 1, Z, 1a, etc). The last part of the regex ({2,4}) defines an interval expression. This means that it can match a minimum of 2 of the thing that precedes it, and a maximum of 4.
Hope you got something out of the above.
There is an awesome explanation of regular expressions at http://www.regular-expressions.info/ including notes on language and implementation specifics.
Let me explain:
Check if all numbers: /^[0-9]+$/
So, first thing we see is the "/" at the beginning and the end. This is a deliminator, and only serves to show the beginning and end of the regular expression.
Next, we have a "^", this means the beginning of the string. [0-9] means a number from 0-9. + is a modifier, which modifies the term in front of it, in this case, it means you can have one or more of something, so you can have one or more numbers from 0-9.
Finally, we end with "$", which is the opposite of "^", and means the end of the string. So put that all together and it basically makes sure that inbetween the start and end of the string, there can be any number of digits from 0-9.
Check if all letters: /^[a-zA-Z]+$/
We notice this is very similar, but instead of checking for numbers 0-9, it checks for letters a-z (lowercase) and A-Z (uppercase).
And the hardest one:
Validate Email: /^[\w-.+]+\#[a-zA-Z0-9.-]+.[a-zA-z0-9]{2,4}$/
"\w" means that it is a word, in this case we can have any number of letters or numbers, as well as the period means that it can be pretty much any character.
The new thing here is escape characters. Many symbols cannot be used without escaping them by placing a slash in front, as is the case with "\#". This means it is looking directly for the symbol "#".
Now it looks for letters and symbols, a period (this one seems incorrect, it should be escaping the period too, though it will still work, since an unescaped period will make any symbol). Numbers inside {} mean that there is inbetween this many terms in the previous term, so of the [a-zA-Z0-9], there should be 2-4 characters (this part here is the website domain, such as .com, .ca, or .info). Note there's another error in this one here, the [a-zA-z0-9] should be [a-zA-Z0-9] (capital Z).
Oh, and check out that site listed above, it is a great set of tutorials too.
Regular Expressions is a complex beast and, as already pointed out, there are quite a few guides off of google you can go read.
To answer the OP questions:
Check if all numbers: /^[0-9]+$/
regexps here are all delimated with //, much like strings are quoted with '' or "".
^ means start of string or line (depending on what options you have about multiline matching)
[...] are called character classes. Anything in [] is a list of single matching characters at that position in this case 0-9. The minus sign has a special meaning of "sequence of characters between". So [0-9] means "one of 0123456789".
+ means "1 or more" of the preceeding match (in this case [0-9]) so one or more numbers
$ means end of string/line match.
So in summary find any string that contains only numbers, i.e '0123a' will not match as [0-9]+ fails to match a before $).
Check if all letters: /^[a-zA-Z]+$/
Hopefully [A-Za-z] makes sense now (A-Z = ABCDEF...XYZ and a-z abcdef...xyz)
Validate Email: /^[\w-.+]+\#[a-zA-Z0-9.-]+.[a-zA-z0-9]{2,4}$/
Not all regexp parses know the \w sequence. Javascript, java and perl I know do support it.
I have already have covered '/^ at the beginning, for this [] match we are looking for
\w - . and +. I think that regexp is incorrect. Either the minus sign should be escaped with \ or it should be at the end of the [] (i.e [\w+.-]). But that is an aside they are basically attempting to allow anything of abcdefghijklmnopqrstuvwxyz01234567890-.+
so fred.smith-foo+wee#mymail.com will match but fred.smith%foo+wee#mymail.com wont (the % is not matched by [\w.+-]).
\# is the litteral atsil sign (it is escaped as perl expands # an array variable reference)
[a-zA-Z0-9.-]+ is the same as [\w.-]+. Very much like the user part of the match, but does not match +. So this matches foo.com. and google.co. but not my+foo.com or my***domain.co.
. means match any one character. This again is incorrect as fred#foo%com will match as . matches %*^%$£! etc. This should of been written as \.
The last character class [a-zA-z0-9]{2,4} looks for between 2 3 or 4 of the a-zA-Z0-9 specified in the character class (much like + looks for "1 more more" {2,4} means at least 2 with a maximum of 4 of the preceeding match. So 'foo' matches, '11' matches, '11111' does not match and 'information' does not.
The "tweaked" regexp should be:
/^[\w.+-]+\#[a-zA-Z0-9.-]+\.[a-zA-z0-9]{2,4}$/
I'm not doing a tutorial on RegEx's, that's been done really well already, but here are what your expressions mean.
/^<something>$/ String begins, has something in the middle, and then immediately ends.
/^foo$/.test('foo'); // true
/^foo$/.test('fool'); // false
/^foo$/.test('afoo'); // false
+ One or more of something:
/a+/.test('cot');//false
/a+/.test('cat');//true
/a+/.test('caaaaaaaaaaaat');//true
[<something>] Include any characters found between the brackets. (includes ranges like 0-9, a-z, and A-Z, as well as special codes like \w for 0-9a-zA-Z_-
/^[0-9]+/.test('f00')//false
/^[0-9]+/.test('000')//true
{x,y} between X and Y occurrences
/^[0-9]{1,2}$/.test('12');// true
/^[0-9]{1,2}$/.test('1');// true
/^[0-9]{1,2}$/.test('d');// false
/^[0-9]{1,2}$/.test('124');// false
So, that should cover everything, but for good measure:
/^[\w-.+]+\#[a-zA-Z0-9.-]+.[a-zA-z0-9]{2,4}$/
Begins with at least character from \w, -, +, or .. Followed by an #, followed by at least one in the set a-zA-Z0-9.- followed by one character of anything (. means anything, they meant \.), followed by 2-4 characters of a-zA-z0-9
As a side note, this regular expression to check emails is not only dated, but it is very, very, very incorrect.

Regex to match card code input

How can I write a regex to match strings following these rules?
1 letter followed by 4 letters or numbers, then
5 letters or numbers, then
3 letters or numbers followed by a number and one of the following signs: ! & # ?
I need to allow input as a 15-character string or as 3 groups of 5 chars separated by one space.
I'm implementing this in JavaScript.
I'm not going to write out the whole regex for you since this is homework, but here are some hints which should help you out:
Use character classes. [A-Z] matches all uppercase. [a-z] matches all lowercase. [0-9] matches numbers. You can combine them like so [A-Za-z0-9].
Use quantifiers like {n} so [A-Z]{3} gives you 3 uppercase letters.
You can put other characters in character classes. Let's say you wanted to match % or # or #, you could do [%##] which would match any of those characters.
Some meta-characters (characters which have special meaning in the context of regular expressions) will need to be escaped like so: \$ (since $ matches the end of a line)
^ and $ match the beginning and end of the line respectively.
\s matches white-space, but if you sanitize your input, you shouldn't need to use this.
Flags after the regex do special things. For example in /[a-z]/i, the i ignores case.
This should be it:
/^[a-z][a-z0-9]{4} ?[a-z0-9]{5} ?[a-z0-9]{3}[0-9][!&#?]$/i
Feel free to change 0-9 and [0-9] with \d if you see fit.
The regex is simple and readable enough. ^ and $ make sure this is a whole match, so there aren't extra characters before or after the code, and the /i flag allows upper or lower case letters.
I would start with a tutorial.
Pay attention to the quantifiers (like {N}) and character classes (like [a-zA-Z])
^[a-zA-Z][a-zA-Z0-9]{4} ?[a-zA-Z0-9]{5} ?[a-zA-Z0-9]{3}[\!\&\#\?]$

Categories

Resources