Regex validation in ASP.Net MVC - c#

In my demo MVC Application I have the following validation rules for validating my domain model classes.
RuleFor(m => m.Password)
.Matches(#"^(?=(\d){2,})(?=([a-z])+)(?=(\.\$\~\&)*)").WithMessage("Password should contain at least 2 digits");
But the password validation fails .
Basically I want to validate that a password input value should at least contain 2 digits, at least either one of the special characters (.$~&) and at least one alphabet in any order.
They can appear in any order.
Basically I should match the strings like
'a2ss1~A33',
'678.&aA88'
but not
'aaa2sfhdjkf^',
'aass'.
Also I just came across lookahead s in regex.
I still have a doubt why cant just we have the rule for validating the password field ?
.Matches(#"^((\d){2,})(.*[a-zA-Z])([\.\$\~\&]*)").WithMessage("Password should contain at least 2 digits");
When to use lookaheads in regex and when not to ?

You can use
^(?=(\D*\d){2})(?=[^A-Za-z]*[A-Za-z])(?=[^.$~&]*[.$~&]).*
See the regex demo.
The regex matches:
^ - start of string
(?=(\D*\d){2}) - 2 digits anywhere in the string are required
(?=[^A-Za-z]*[A-Za-z]) - an ASCII letter is required somewhere in a string
(?=[^.$~&]*[.$~&]) - the symbol from the [.$~&] set is required
.* - (optional, remove if full string match is not required) matches all characters other than a newline up to the end of the line
Lookaheads enable several checks from the same position in string (here, at the very beginning as they are all placed right after ^). The regex ^((\d){2,})(.*[a-zA-Z])([\.\$\~\&]*) requires 2 or more digits at the beginning, followed with any 0+ characters other than a newline followed with 1 letter followed with 0+ some special symbols. There can be anything else after that, since you are not checking the end of the string.

Related

Regex for alpha number string in c# accepting underscore and white spaces

I already gone through many post on SO. I didn't find what I needed for my specific scenario.
I need a regex for alpha numeric string.
where following conditions should be matched
Valid string:
ameya123 (alphabets and numbers)
ameya (only alphabets)
AMeya12(Capital and normal alphabets and numbers)
Ameya_123 (alphabets and underscore and numbers)
Ameya_ 123 (alphabets underscore and white speces)
Invalid string:
123 (only numbers)
_ (only underscore)
(only space) (only white spaces)
any special charecter other than underscore
what i tried till now:
(?=.*[a-zA-Z])(?=.*[0-9]*[\s]*[_]*)
the above regex is working in Regex online editor however not working in data annotation in c#
please suggest.
Based on your requirements and not your attempt, what you are in need of is this:
^(?!(?:\d+|_+| +)$)[\w ]+$
The negative lookahead looks for undesired matches to fail the whole process. Those are strings containing digits only, underscores only or spaces only. If they never happen we want to have a match for ^[\w ]+$ which is nearly the same as ^[a-zA-Z0-9_ ]+$.
See live demo here
Explanation:
^ Start of line / string
(?! Start of negative lookahead
(?: Start of non-capturing group
\d+ Match digits
| Or
_+ Match underscores
| Or
[ ]+ Match spaces
)$ End of non-capturing group immediately followed by end of line / string (none of previous matches should be found)
) End of negative lookahead
[\w ]+$ Match a character inside the character set up to end of input string
Note: \w is a shorthand for [a-zA-Z0-9_] unless u modifier is set.
One problem with your regex is that in annotations, the regex must match and consume the entire string input, while your pattern only contains lookarounds that do not consume any text.
You may use
^(?!\d+$)(?![_\s]+$)[A-Za-z0-9\s_]+$
See the regex demo. Note that \w (when used for a server-side validation, and thus parsed with the .NET regex engine) will also allow any Unicode letters, digits and some more stuff when validating on the server side, so I'd rather stick to [A-Za-z0-9_] to be consistent with both server- and client-side validation.
Details
^ - start of string (not necessary here, but good to have when debugging)
(?!\d+$) - a negative lookahead that fails the match if the whole string consists of digits
(?![_\s]+$) - a negative lookahead that fails the match if the whole string consists of underscores and/or whitespaces. NOTE: if you plan to only disallow ____ or " " like inputs, you need to split this lookahead into (?!_+$) and (?!\s+$))
[A-Za-z0-9\s_]+ - 1+ ASCII letters, digits, _ and whitespace chars
$ - end of string (not necessary here, but still good to have).
If I understand your requirements correctly, you need to match one or more letters (uppercase or lowercase), and possibly zero or more of digits, whitespace, or underscore. This implies the following pattern:
^[A-Za-z0-9\s_]*[A-Za-z][A-Za-z0-9\s_]*$
Demo
In the demo, I have replaced \s with \t \r, because \s was matching across all lines.
Unlike the answers given by #revo and #wiktor, I don't have a fancy looking explanation to the regex. I am beautiful even without my makeup on. Honestly, if you don't understand the pattern I gave, you might want to review a good regex tutorial.
This simple RegEx should do it:
[a-zA-Z]+[0-9_ ]*
One or more Alphabet, followed by zero or more numbers, underscore and Space.
This one should be good:
[\w\s_]*[a-zA-Z]+[\w\s_]*

Regex for a Complex Password

I've got this Regex as a data annotation on a password field in a C# .NET MVC project.
[RegularExpression("(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[*+\\/|!\"£$%^&*()#[\\]#~'?><,.=-_]).{6,}", ErrorMessage = "Password must be between 6 and 20 characters and contain one uppercase letter, one lowercase letter, one digit and one special character.")]
I want to make the following passwords invalid:-
Testing
Testing1
TesTinG123
The following would be valid:-
Testing1*
T&sting123*
%F&y5HD$S
I would like a minimum of 6 characters, with at least one uppercase, one lower case, one digit and one special character. I hope the above regex would do it, but it lets Testing12 and Tester12 through as valid passwords.
What can I change in the above to get what I am expecting? I assumed the above requires one uppercase, one lowercase, one numeric and one special character but obviously I am wrong?
Thanks in advance!
You forgot to escape ] properly (it is advised to even put it at the start of the character class so that in .NET it could be parsed as a literal ] - for the client side validation, it needs to be escaped even there) and remember that a hyphen inside a character class creates a range (e.g. [=-_]), so it must be put at the end/start of the character class or at the end to denote a literal -).
Use
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[\]*+\\/|!\"£$%^&*()#[#~'?><,.=_-]).{6,}$"
^^ ^
Or, if you just want to require at least 1 char that is not alphanumeric, use
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_]).{6,}$"
where [\W_] matches any char but a word char (i.e. [^\p{L}\p{N}_] or - on client side - [^a-zA-Z0-9_]) + _.
The ^ and $ anchors are redundant in the RegularExpressionAttribute pattern, but they won't do any harm.
See the regex demo.

Regex c#: Last Name in an email to include only one hyphen

Friends,
I have a textbox, which takes firstname.Lastname for my organisation.
The last name may or may not include hyphen.If it includes, then it should appear,
1) Only once in last name
2) Not at the beginning of lastname
3) not at the end of last name
I have this Regex figured out
^(?!.{51})[a-zA-Z]+(?:[.][a-zA-Z-]+)?$
This includes "-" in last name. But will not satisfy above conditions.
Im still learning regex, and is taking time to figure out this.
Please help
-Thank you
You need to add one more nested group inside the last name part:
^(?!.{51})[a-zA-Z]+(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)?$
^^^^^^^^^^^^^^^
See the regex demo
Details:
^ - start of string
(?!.{51}) - no more than 50 chars in the string requirement
[a-zA-Z]+ - 1+ ASCII letters
(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)? - an optional sequence of:
\. - a dot
[a-zA-Z]+ - 1 or more ASCII letters
(?:-[a-zA-Z]+)? - an optional sequence of:
- - a hyphen
[a-zA-Z]+ - 1+ ASCII letters
$ - end of string.
To declare this pattern, use a verbatim string literal:
var pattern = #"^(?!.{51})[a-zA-Z]+(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)?$";
To match any Unicode letters, use \p{L} instead of [a-zA-Z].
This is a somehow Quick and Dirty Solution.
^(?!.{51})[a-zA-Z]+.{1}[a-zA-Z]{1,}-?[a-zA-Z]+$
The first part of the string is still used from you. It seem to match just perfect.
My Addition .{1}[a-zA-Z]{1,}-?[a-zA-Z]+ simply describes what happens next.
[a-zA-Z]{1,} makes sure that there is at least one charackter after the dot, so no "-" can be written as beginning.
-?just describes that there may be appear a "-" somewhere after the first characters has been written.
[a-zA-Z]+ just says that there may come as many characters as the user want's. But not a "-" anymore.

Regex validations in asp.net

I want that it should start with alphabet and it's up to user if he/she wants to add numerical but there should be no special characters and should start with alphabet.
I tried "^[A-Za-z][0-9]+$"
but it's not working..
Correct format:
ASDFG123
asdfg123
a1231sadas
Wrong format:
asdfg_123
Asdfg-31
You could try the below regex, in which the string must be start with alphabets followed by one or more digits and again followed by zero or more times alphabets or numbers.
^[A-Za-z]+[0-9]+[A-Za-z0-9]*$
DEMO
You could try the below regex if the input may or maynot contain numbers,
^[A-Za-z]+[A-Za-z0-9]*$
DEMO
Pattern Explanation:
^ Asserts that we are at the start.
[A-Za-z]+ Allows one or more times alphabets(both uppercase and lowercase). + means repeat the preceding token one or more times. In our case the preceding token is the character class.
[A-Za-z0-9]* Allows zero or more times alphabets or numbers. * means repeat the preceding token zero or more times.
$ End of the line.

Explain the Regex mentioned

Can any one please explain the regex below, this has been used in my application for a very long time even before I joined, and I am very new to regex's.
/^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$/
As far as I understand
this regex will validate
- for a minimum of 6 chars to a maximum of 10 characters
- will escape the characters like ^ and $
also, my basic need is that I want a regex for a minimum of 6 characters with 1 character being a digit and the other one being a special character.
^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$
^ is called an "anchor". It basically means that any following text must be immediately after the "start of the input". So ^B would match "B" but not "AB" because in the second "B" is not the first character.
.* matches 0 or more characters - any character except a newline (by default). This is what's known as a greedy quantifier - the regex engine will match ("consume") all of the characters to the end of the input (or the end of the line) and then work backwards for the rest of the expression (it "gives up" characters only when it must). In a regex, once a character is "matched" no other part of the expression can "match" it again (except for zero-width lookarounds, which is coming next).
(?=.{6,10}) is a lookahead anchor and it matches a position in the input. It finds a place in the input where there are 6 to 10 characters following, but it does not "consume" those characters, meaning that the following expressions are free to match them.
(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z]) is another lookahead anchor. It matches a position in the input where the following text contains four letters ([a-zA-Z] matches one lowercase or uppercase letter), but any number of other characters (including zero characters) may be between them. For example: "++a5b---C#D" would match. Again, being an anchor, it does not actually "consume" the matched characters - it only finds a position in the text where the following characters match the expression.
(?=.*\d.*\d) Another lookahead. This matches a position where two numbers follow (with any number of other characters in between).
.* Already covered this one.
$ This is another kind of anchor that matches the end of the input (or the end of a line - the position just before a newline character). It says that the preceding expression must match characters at the end of the string. When ^ and $ are used together, it means that the entire input must be matched (not just part of it). So /bcd/ would match "abcde", but /^bcd$/ would not match "abcde" because "a" and "e" could not be included in the match.
NOTE
This looks like a password validation regex. If it is, please note that it's broken. The .* at the beginning and end will allow the password to be arbitrarily longer than 10 characters. It could also be rewritten to be a bit shorter. I believe the following will be an acceptable (and slightly more readable) substitute:
^(?=(.*[a-zA-Z]){4})(?=(.*\d){2}).{6,10}$
Thanks to #nhahtdh for pointing out the correct way to implement the character length limit.
Check Cyborgx37's answer for the syntax explanation. I'll do some explanation on the meaning of the regex.
^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$
The first .* is redundant, since the rest are zero-width assertions that begins with any character ., and .* at the end.
The regex will match minimum 6 characters, due to the assertion (?=.{6,10}). However, there is no upper limit on the number of characters of the string that the regex can match. This is because of the .* at the end (the .* in the front also contributes).
This (?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z]) part asserts that there are at least 4 English alphabet character (uppercase or lowercase). And (?=.*\d.*\d) asserts that there are at least 2 digits (0-9). Since [a-zA-Z] and \d are disjoint sets, these 2 conditions combined makes the (?=.{6,10}) redundant.
The syntax of .*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z] is also needlessly verbose. It can be shorten with the use of repetition: (?:.*[a-zA-Z]){4}.
The following regex is equivalent your original regex. However, I really doubt your current one and this equivalent rewrite of your regex does what you want:
^(?=(?:.*[a-zA-Z]){4})(?=(?:.*\d){2}).*$
More explicit on the length, since clarity is always better. Meaning stay the same:
^(?=(?:.*[a-zA-Z]){4})(?=(?:.*\d){2}).{6,}$
Recap:
Minimum length = 6
No limit on maximum length
At least 4 English alphabet, lowercase or uppercase
At least 2 digits 0-9
REGEXPLANATION
/.../: slashes are often used to represent the area where the regex is defined
^: matches beginning of input string
.: this can match any character
*: matches the previous symbol 0 or more times
.{6,10}: matches .(any character) somewhere between 6 and 10 times
[a-zA-Z]: matches all characters between a and z and between A and Z
\d: matches a digit.
$: matches the end of input.
I think that just about does it for all the symbols in the regex you've posted
For your regex request, here is what you would use:
^(?=.{6,}$)(?=.*?\d)(?=.*?[!##$%&*()+_=?\^-]).*
And here it is unrolled for you:
^ // Anchor the beginning of the string (password).
(?=.{6,}$) // Look ahead: Six or more characters, then the end of the string.
(?=.*?\d) // Look ahead: Anything, then a single digit.
(?=.*?[!##$%&*()+_=?\^-]) // Look ahead: Anything, and a special character.
.* // Passes our look aheads, let's consume the entire string.
As you can see, the special characters have to be explicitly defined as there is not a reserved shorthand notation (like \w, \s, \d) for them. Here are the accepted ones (you can modify as you wish):
!, #, #, $, %, ^, &, *, (, ), -, +, _, =, ?
The key to understanding regex look aheads is to remember that they do not move the position of the parser. Meaning that (?=...) will start looking at the first character after the last pattern match, as will subsequent (?=...) look aheads.

Categories