Regex - I need to include non-alphabetic character - c#

i have this expression and i need to make sure to include at least one non-alphabetic character
^(?!.*(.)\1)\S{8,12}$
testhis invalid
testhis7 valid
testhis# valid

You could use a positive lookahead asserting at least 1 char other than a-zA-Z
^(?!.*(.)\1)(?=.*[^\sa-zA-Z])\S{8,12}$
Explanation
^ Start of string
(?!.*(.)\1) Assert not 2 consecutive chars
(?=.*[^\sa-zA-Z]) Assert 1 char other than a whitespace char and a-zA-Z
\S{8,12} Match 8-12 non whitespace chars
$ End of string
Regex demo
Another option is to use \P{L} to assert any char other than any kind of letter from any language
^(?!.*(.)\1)(?=.*\P{L})\S{8,12}$
Regex demo

You can just check for the special character (as matched by [\p{P}\p{S}]) in positive lookahead (?=.*[\p{P}\p{S}]), which gives you the regex:
^(?!.*(.)\1)(?=.*[\p{P}\p{S}])\S{8,12}$
See online demo
You can also replace [\p{P}\p{S}] by [!"\#$%&'()*+,\-./:;<=>?#\[\\\]^_‘{|}~], or any other character set that list all the characters that you want to count as being "special characters".

It's better to do it with separate if-statements. This way you'll have exact information what is missing in the value. With regexps you'll only get a true/false result if the value matched the pattern or not - you'll have no information WHAT is missing in the value.
For example:
if(!value.Any(c => !char.IsLetter(c)){
throw new Exception("value must contain at least one non-letter")
}

Related

Regularexpression for duplicate pattern

I am trying to write a regex to handle these cases
contains only alphanumeric with minimum of 2 alpha characters(numbers are optional).
only special character allowed is hyphen.
cannot be all same letter ignoring hyphen.
cannot be all hyphens
cannot be all numeric
My regex: (?=[^A-Za-z]*[A-Za-z]){2}^[\w-]{6,40}$
Above regex works for most of the scenarios except 1) & 3).
Can anyone suggest me to fix this. I am stuck in this.
Regards,
Sajesh
Rule 1 eliminates rule 4 and 5: It can neither contain only hyphens, nor only digits.
/^(?=[a-z\d-]{6,40}$)[\d-]*([a-z]).*?(?!\1)[a-z].*$/i
(?=[a-z\d-]{6,40}$) look ahead for specified characters from 6 to 40
([a-z]).*?(?!\1)[a-z] checks for two letters and at least one different
See this demo at regex101
This pattern with i flag considers A and a as the "same" letter (caseless matching) and will require another alpbhabet. For case sensitive matching here another demo at regex101.
You can use
^(?!\d+$)(?!-+$)(?=(?:[\d-]*[A-Za-z]){2})(?![\d-]*([A-Za-z])(?:[\d-]*\1)+[\d-]*$)[A-Za-z\d-]{6,40}$
See the regex demo. If you use it in C# or PHP, consider replacing ^ with \A and $ with \z to make sure you match the entire string even in case there is a trailing newline.
Details:
^ - start of string
(?!\d+$) - fail the match if the string only consists of digits
(?!-+$) - fail the match if the string only consists of hyphens
(?=(?:[\d-]*[A-Za-z]){2}) - there must be at least two ASCII letters after any zero or more digits or hyphens
(?![\d-]*([A-Za-z])(?:[\d-]*\1)+[\d-]*$) - fail the match if the string contains two or more identical letters (the + after (?:[\d-]*\1) means there can be any one letter)
[A-Za-z\d-]{6,40} - six to forty alphanumeric or hyphen chars
$ - end of string. (\z might be preferable.)

C# How to filtered datatable rows which containing alphanumeric with special characters using Regex

I have below data in my C# Datatable
What I want is to filter those data which has Alphanumeric with special characters like:
HOAUD039#
HOAUD00$
So I try below regex in my linq query:
var matches =
dt.AsEnumerable()
.Where(row => Regex.IsMatch(row["Empolyee_CRC"].ToString(),
"^[a-zA-Z0-9!##$&()\\-`.+,/\"]*$"))
.CopyToDataTable();
which returns me both Alphanumeric result and Alphanumeric with characters like below:
Now my question is simple and clear what is the right way to show results only having Alphanumeric with special characters.
I've also tried this regex but it is also not work
^(?:[\d,\/().]*[a-zA-Z][a-zA-Z\d,\/().]*)?$
You can try this based on your example patterns this will serve
^(?=.*\d)(?=.*[A-Za-z])(?=.*[!##$&()\\-`.+,\/\"]).*$
Explanation
^ - Anchor to start of string.
(?=.*\d) - Condition for checking at least one digit must be there in match.
(?=.*[A-Za-z]) - Condition for checking at least one character must be there in match.
(?=.*[!##$&()\\-.+,/\"])` - Condition for checking at least one special must be there in match.
.* - Match anything except newline.
$ - End of string.
Demo
In your regex you are using a single chararacter class which will only select one out of many, but your have 3 requirements.
In your second regex, everything is optional due to the * and the ?
You could use 3 positive lookaheads to assert your requirements:
^(?=.*\d)(?=.*[!##$&()`.+,\/\-])(?=.*[A-Z])[A-Z\d!##$&()`.+,\/\-]+$
In C#:
string pattern = #"^(?=.*\d)(?=.*[!##$&()`.+,\/\-])(?=.*[a-zA-Z])[a-zA-Z\d!##$&()`.+,\/-]+$";
That will match:
^ Start of string
(?=.*\d) Assert a digit
(?=.*[!##$&().+,/-])` Assert a special character
(?=.*[A-Za-z]) Assert a lowercase or uppercase character
[A-Za-z\d!##$&().+,/-]+` Match 1+ times only the allowed characters
$ End of the string
Regex demo | C# Demo

Regular expression thingy

I would like to create a custom regular expression. Which shall track that the first character of a username should be an alphabet.
Followed by alphanumeric or can have maximum one occurrence of a special character (- or _). I can check for username starts with the alphabet with this ^[a-zA-Z]+$ but not sure what to do to check at most one occurrence of a special character. Any ideas are welcome.
Thanks
From what I understood of your post, you want the following to match.
a-afdsafd
aafdsafd
aafdsa_fd
aafdsa-fd
aAfdsa-FD
And the following to not match:
aa-dsa-fd
aa-dsa_fd
-afdsafd
_afdsafd
Try /^[a-z](?:(?![a-z]+[\-_])[\-_])?[a-z]+(?:(?<![a-z]+[\-_])[\-_]?)[a-z]+?$/i
The i modifier enables case-insensitive matching.
The ^ and $ anchors ensure that the entire string matches our regex.
[a-z] checks that the first character is an alphabet.
(?:(?![a-z]+[\-_])[\-_])?) looks ahead to check that there is no "special character" used later and if there is none, we optionally match one special character.
[a-z]+ Match one or more alphabets.
(?:(?<![a-z]+[\-_])[\-_]?) does the same thing as 4 except it looks behind.
[a-z]+? Optionally match one or more alphabets.
https://regexr.com/3t86l
Edit: I noticed that aAfdsaFd_ should also match. The above does not match this. Slightly modifying #Wiktor Stribiżew's comment, ^[a-zA-Z][a-zA-Z0-9]*(?:[-_][a-zA-Z0-9]*)?$ seems to work fine with all cases. That's cleaner and more efficient. All credit to #Wiktor Stribiżew.
You could match an upper or lowercase character from the start of the string ^[a-zA-Z], match zero or more times alphanumeric [a-zA-Z0-9]* followed by an optional hyphen or underscore [-_]?.
At the end match zero or more times alphanumeric [a-zA-Z0-9]*$ until the end of the string.
^[a-zA-Z][a-zA-Z0-9]*[-_]?[a-zA-Z0-9]*$

Why does this Regex match?

I have written a regular expression to match the following criteria
any digit (0-9)
hyphen
whitespace
in any order
length between 10 and 25
([0-9\-\w]{10,25})
I am using it to detect payment card numbers, so this works:
Regex.IsMatch("34343434343434", "([0-9\\-\\w]{10,25})"); // true
But this also works:
Regex.IsMatch("LogMethodComplete", "([0-9\\-\\w]{10,25})"); // true
What am I doing wrong?
This is C#
Take a look at Regular Expression Language - Quick Reference, section Character Classes.
\w matches any word character including underscore, not whitespace.
To match whitespace, you can use \s.
To match digits, you can use \d.
Instead of using \w you can use \d which means digit you could use regex like
"[\d\-\s]{10,25}" to match your criteria
You don't need to check for "words" and this is what \w does

Better way to write this RegEx?

I have this password regex for an application that is being built its purpose is to:
Make sure users use between 6 - 12 characters.
Make sure users use either one special character or one number.
Also that its case insensitive.
The application is in .net I have the following regex:
I have the following regex for the password checker, bit lengthy but for your viewing if you feel any of this is wrong please let me know.
^(?=.*\d)(?=.*[A-Za-z]).{6-12}$|^(?=.*[A-Za-z])(?=.*[!#$%&'\(\)\*\+-\.:;<=>\?#\[\\\]\^_`\{\|\}~0x0022]|.*\s).{6,12}$
Just a break down of the regex to make sure your all happy it’s correct.
^ = start of string ”^”
(?=.*\d) = must contain “?=” any set of characters “.*” but must include a digit “\d”.
(?=.*[A-Za-z]) = must contain “?=” any set of characters “.*” but must include an insensitive case letter.
.{6-12}$ = must contain any set of characters “.” but must have between 6-12 characters and end of string “$”.
|^ = or “|” start of string “^”
(?=.*[A-Za-z]) = must contain “?=” any set of characters “.*” but must include an insensitive case letter.
(?=.*[!#$%&'\(\)\*\+-\.:;<=>\?#\[\\\]\^_`\{\|\}~0x0022]|.*\s) = must contain “?=” any set of characters “.*” but must include at least special character we have defined or a space ”|.*\s)”. “0x0022” is Unicode for single quote “ character.
.{6,12}$ = set of characters “.” must be between 6 – 12 and this is the end of the string “$”
It's quite long winded, seems to be doing the job but I want to know if there is simpler methods to write this sort of regex and I want to know how I can shorten it if its possible?
Thanks in Advanced.
Does it have to be regex? Looking at the requirements, all you need is String.Length and String.IndexOfAny().
First, good job at providing comments for your regex. However, there is a much better way. Simply write your regex from the get-go in free-spacing mode with lots of comments. This way you can document your regex right in the source code (and provide indentation to improve readability when there are lots of parentheses). Here is how I would write your original regex in C# code:
if (Regex.IsMatch(usernameString,
#"# Validate username having a digit and/or special char.
^ # Either... Anchor to start of string.
(?=.*\d) # Assert there is a digit AND
(?=.*[A-Za-z]) # assert there is an alpha.
.{6-12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
| ^ # Or... Anchor to start of string
(?=.*[A-Za-z]) # Assert there is an alpha AND
(?=.* # assert there is either a special char
[!#$%&'\(\)\*\+-\.:;<=>\?#\[\\\]\^_`\{\|\}~\x22]
| .*\s # or a space char.
) # End specialchar-or-space assertion.
.{6-12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
The code snippet above uses the preferable #"..." string syntax which simplifies the escaping of metacharacters. This original regex erroneously separates the two numbers of the curly brace quantifier using a dash, i.e. .{6-12}. The correct syntax is to separate these numbers with a comma, i.e. .*{6,12}. (Maybe .NET allows using the .{6-12} syntax?) I've also changed the 0x0022 (the " double quote char) to \x22.
That said, yes the original regex can be improved a bit:
if (Regex.IsMatch(usernameString,
#"# Validate username having a digit and/or special char.
^ # Anchor to start of string.
(?=.*?[A-Za-z]) # Assert there is an alpha.
(?: # Group for assertion alternatives.
(?=.*?\d) # Either assert there is a digit
| # or assert there is a special char
(?=.*?[!#$%&'()*+-.:;<=>?#[\\\]^_`{|}~\x22\s]) # or space.
) # End group of assertion alternatives.
.{6,12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
This regex eliminates the global alternative and instead uses a non-capture group for the "digit or specialchar" assertion alternatives. Also, you can eliminate the non-capture group for the "special char or whitespace" alternatives by simply adding the \s to the list of special chars. I've also added a lazy modifier to the dot-stars in the assertions, i.e. .*? - (this may make the regex match a bit faster.) A bunch of unnecessary escapes were removed from the specialchar character class.
But as Stema cleverly pointed out, you can combine the digit and special char to simplify this even further:
if (Regex.IsMatch(usernameString,
#"# Validate username having a digit and/or special char.
^ # Anchor to start of string
(?=.*?[A-Za-z]) # Assert there is an alpha.
# Assert there is a special char, space
(?=.*?[!#$%&'()*+-.:;<=>?#[\\\]^_`{|}~\x22\s\d]) # or digit.
.{6,12} # Match any name with length from 6 to 12.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace)) {
// Valid username.
} else {
// Invalid username.
}
Other than that, there is really nothing wrong with your original regex with regard to accuracy. However, logically, this formula allows a username to end with whitespace which is probably not a good idea. I would also explicitly specify a whitelist of allowable chars in the name rather than using the overly permissive "." dot.
I am not sure if it makes sense what you are doing, but to achieve that, your regex can be simpler
^(?=.*[A-Za-z])(?=.*[\d\s!#$%&'\(\)\*\+-\.:;<=>\?#\[\\\]\^_`\{\|\}~0x0022]).{6,12}$
Why using alternatives? Just Add \d and \s to the character class.

Categories

Resources