C# RegularExpression Model Validation Length - c#

Question: How can I write this without putting in all the possible cases? If someone gets 4 password requirements one day it will be easy to put in but be very difficult to debug since there will be 4! different ways to work the middle.
How I have it in code:
[RegularExpression("^[A-Za-z0-9!##$]*([A-Za-z][0-9][!##$]|[0-9][!##$][A-Za-z]|[!##$][A-Za-z][0-9]|[!##$][0-9][A-Za-z]|[0-9][A-Za-z][!##$]|[A-Za-z][!##$][0-9])[A-Za-z0-9!##$]*$", ErrorMessage = "The Password value must contain at least one letter, one digit, and one special character.")]
For viewing convenience I broke it so no scrolling is required:
[RegularExpression("^[A-Za-z0-9!##$]*
([A-Za-z][0-9][!##$]|[0-9][!##$][A-Za-z]|
[!##$][A-Za-z][0-9]|[!##$][0-9][A-Za-z]|
[0-9][A-Za-z][!##$]|[A-Za-z][!##$][0-9])
[A-Za-z0-9!##$]*$",
ErrorMessage = "The Password value must contain at least one letter,
one digit, and one special character.")]
As you can see this is 3! possibilities from the middle () separated by | (OR) so from this you can see 4! possibilities would be very difficult to maintain.
Question Requirements: The basic thing I want this RegularExpression in C# to do is require (in no particular order) at least one letter, at least one number, at least one special character !, #, #, or $

One Regex
You can use zero-width positive lookahead assertions (see MSDN's "Regular Expression Language - Quick Reference" - in the Grouping Constructs section) to check for your ANDed password requirements - without having to explicitly cover all the orders in which the required password components may occur:
^(?=.*?[a-zA-Z])(?=.*?[0-9])(?=.*?[!##$]).{3,}$
This works as follows:
(?=.*?[a-zA-Z]) - an alpha character found ahead
(?=.*?[0-9]) - and a number found ahead
(?=.*?[!##$]) - and an allowed special character ahead
.{3,} - three or more characters in total
I have shared a regex fiddle based on this that you might find useful.
Property-Per-Criterion Password Checker
Per #LeffeBrune's comment, you should consider alternatively checking with a dedicated password-checker class that exposes a property per criterion.
For example, here is a quick & dirty PoC in LINQPad 4...
void Main()
{
var passwords = new string[] {"password", "passw0rd", "passw0rd!", "123456", "!##$"};
foreach (var pw in passwords)
{
var checker = new PasswordChecker(pw);
var isValid = checker.IsValid;
Console.WriteLine("Password {0} is {1}valid.", pw, isValid ? "" : "in");
if (!isValid)
{
Console.WriteLine(" Has alpha? {0}", checker.HasAlpha ? "Yes." : "NO!");
Console.WriteLine(" Has number? {0}", checker.HasNumber ? "Yes." : "NO!");
Console.WriteLine(" Has special? {0}", checker.HasSpecial ? "Yes." : "NO!");
Console.WriteLine(" Has length? {0}", checker.HasLength ? "Yes." : "NO!");
}
}
}
public class PasswordChecker
{
public const int MINIMUM_LENGTH = 3;
private string _password;
public PasswordChecker(string password)
{
_password = password;
}
public bool HasAlpha
{
get
{
return Regex.Match(_password, "(?=.*?[a-zA-Z])").Success;
}
}
public bool HasNumber
{
get
{
return Regex.Match(_password, "(?=.*?[0-9])").Success;
}
}
public bool HasSpecial
{
get
{
return Regex.Match(_password, "(?=.*?[!##$])").Success;
}
}
public bool HasLength
{
get
{
return _password.Length >= MINIMUM_LENGTH;
}
}
public bool IsValid
{
get
{
return HasLength && HasAlpha && HasNumber && HasSpecial;
}
}
}
...that produces the following output:
Password password is invalid.
Has alpha? Yes.
Has number? NO!
Has special? NO!
Has length? Yes.
Password passw0rd is invalid.
Has alpha? Yes.
Has number? Yes.
Has special? NO!
Has length? Yes.
Password passw0rd! is valid.
Password 123456 is invalid.
Has alpha? NO!
Has number? Yes.
Has special? NO!
Has length? Yes.
Password !##$ is invalid.
Has alpha? NO!
Has number? NO!
Has special? Yes.
Has length? Yes.
You could take this quick & dirty PoC much further of course, but the benefits of knowing what criterion or criteria failed are hopefully clear.

Related

Regex for string without spacial characters or spaces [duplicate]

How do I check a string to make sure it contains numbers, letters, or space only?
In C# this is simple:
private bool HasSpecialChars(string yourString)
{
return yourString.Any(ch => ! char.IsLetterOrDigit(ch));
}
The easiest way it to use a regular expression:
Regular Expression for alphanumeric and underscores
Using regular expressions in .net:
http://www.regular-expressions.info/dotnet.html
MSDN Regular Expression
Regex.IsMatch
var regexItem = new Regex("^[a-zA-Z0-9 ]*$");
if(regexItem.IsMatch(YOUR_STRING)){..}
string s = #"$KUH% I*$)OFNlkfn$";
var withoutSpecial = new string(s.Where(c => Char.IsLetterOrDigit(c)
|| Char.IsWhiteSpace(c)).ToArray());
if (s != withoutSpecial)
{
Console.WriteLine("String contains special chars");
}
Try this way.
public static bool hasSpecialChar(string input)
{
string specialChar = #"\|!#$%&/()=?»«#£§€{}.-;'<>_,";
foreach (var item in specialChar)
{
if (input.Contains(item)) return true;
}
return false;
}
String test_string = "tesintg#$234524##";
if (System.Text.RegularExpressions.Regex.IsMatch(test_string, "^[a-zA-Z0-9\x20]+$"))
{
// Good-to-go
}
An example can be found here: http://ideone.com/B1HxA
If the list of acceptable characters is pretty small, you can use a regular expression like this:
Regex.IsMatch(items, "[a-z0-9 ]+", RegexOptions.IgnoreCase);
The regular expression used here looks for any character from a-z and 0-9 including a space (what's inside the square brackets []), that there is one or more of these characters (the + sign--you can use a * for 0 or more). The final option tells the regex parser to ignore case.
This will fail on anything that is not a letter, number, or space. To add more characters to the blessed list, add it inside the square brackets.
Use the regular Expression below in to validate a string to make sure it contains numbers, letters, or space only:
[a-zA-Z0-9 ]
You could do it with a bool. I've been learning recently and found I could do it this way. In this example, I'm checking a user's input to the console:
using System;
using System.Linq;
namespace CheckStringContent
{
class Program
{
static void Main(string[] args)
{
//Get a password to check
Console.WriteLine("Please input a Password: ");
string userPassword = Console.ReadLine();
//Check the string
bool symbolCheck = userPassword.Any(p => !char.IsLetterOrDigit(p));
//Write results to console
Console.WriteLine($"Symbols are present: {symbolCheck}");
}
}
}
This returns 'True' if special chars (symbolCheck) are present in the string, and 'False' if not present.
A great way using C# and Linq here:
public static bool HasSpecialCharacter(this string s)
{
foreach (var c in s)
{
if(!char.IsLetterOrDigit(c))
{
return true;
}
}
return false;
}
And access it like this:
myString.HasSpecialCharacter();
private bool isMatch(string strValue,string specialChars)
{
return specialChars.Where(x => strValue.Contains(x)).Any();
}
Create a method and call it hasSpecialChar with one parameter
and use foreach to check every single character in the textbox, add as many characters as you want in the array, in my case i just used ) and ( to prevent sql injection .
public void hasSpecialChar(string input)
{
char[] specialChar = {'(',')'};
foreach (char item in specialChar)
{
if (input.Contains(item)) MessageBox.Show("it contains");
}
}
in your button click evenement or you click btn double time like that :
private void button1_Click(object sender, EventArgs e)
{
hasSpecialChar(textbox1.Text);
}
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the [https://www.nuget.org/packages/Extensions.cs][1] package to your project.
Add "using Extensions;" to the top of your code.
"smith23#".IsAlphaNumeric() will return False whereas "smith23".IsAlphaNumeric() will return True. By default the .IsAlphaNumeric() method ignores spaces, but it can also be overridden such that "smith 23".IsAlphaNumeric(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphaNumeric().
Based on #prmph's answer, it can be even more simplified (omitting the variable, using overload resolution):
yourString.Any(char.IsLetterOrDigit);
No special characters or empty string except hyphen
^[a-zA-Z0-9-]+$

My regex match positive real numbers doesn't work

I am reading from a TextBox in C# and I want to make sure that only real positive values are allowed (including integers).
i.e. 1, 23, 23., 23.0, 23.42, etc.
The Regex I am using is:
[0-9]+\\.?[0-9]*
But C# does only let me type numbers and I can never put a period.
Thank you
Code:
private static readonly Regex rgx_onlyPositiveReals = new Regex("[0-9]+\\.?[0-9]*");
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !IsSamplingRateAllowed(e.Text);
}
private static bool IsSamplingRateAllowed(string text)
{
if(rgx_onlyPositiveReals.IsMatch(text))
{
if(text.Equals(".") || float.Parse(text) <= 0.0)
{
MessageBox.Show("Sampling Rate has to be positive.", "Wrong Sampling Frequency Error", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
return true;
}
return false;
}
From the looks of things this input box is supposed to only contain the number and no other text; in this case I would avoid the regular expression altogether.
Given that you're parsing the regex match result into a float anyway, it might make more sense to try parsing the input as a float directly which has the added benefits of allowing any valid positive float that can be parsed in the first place, it also allows entering the number in any other valid formats supported by float.Parse/float.TryParse e.g. scientific notation "1E5" == 100000f or commas "1,500" == 1500f (depending on the culture) without any additional effort.
private static bool IsSamplingRateAllowed(string text)
{
float number;
return float.TryParse(text, out number) && number >= 0.0f;
}
Unless this data is being used for some external process as a string with additional restrictions on the format (which seems unlikely and is worth including in the question if that is the case), then if it isn't already, I'd recommend separating this input box from any other information and have users enter the number and only the number directly into the box. If you need to collect other information from the user you can add other input boxes and controls as necessary (which can also simplify validation for other pieces of information).
Give this a try
The pattern is ^[0-9]+\.?[0-9]*
In C# you can prefix your string with # which makes it easier to read a regex. It results in the following:
"\\this \\is \\the \\same" == #"\this \is \the \same"
You can simply use the below Regex
^\d*[.]?\d*$
Demo Fiddle

Issue with Validating Phone number on user input,Int to large c#

Overview of Project:
I am creating a multi form application, which consist of two forms and one parent class. Both Forms have a series of validation functions, such as isLetter() isNumber() and isValidEmail(). My Issue comes when using the isNumber() Function.
public static bool numValidation(string strNum)
{
if (!string.IsNullOrWhiteSpace(strNum))
{
int temp;
if (int.TryParse(strNum, out temp))
{
Console.WriteLine("Phone Number is a valid input: " + temp);
return true;
}
else
{ Console.WriteLine(temp + "Is not Valid input!!"); }
}
return false;
}
At first glance it works fine but once I tried to break it, I realised that when an actual phone number is entered I get an error saying that the number is too high. Any ideas how to get round this constraint ? as the only reason I need this validation is for phone numbers, Fax etc. I simply need this function to accept very large numbers such as phone numbers
I suggest that you use a regular expresion to validate the input in your case
public static bool numValidation(string strNum)
{
Regex regex = new Regex(#"^[0-9]+$");
return (regex.IsMatch(strNum)) ;
}
Parsing a string and not using that value is not really needed.
For more details checkout this answers - Regex for numbers only
From Mauricio Gracia Gutierrez answer
I suggest that you use a regular expresion to validate the
input in your case
public static bool numValidation(string strNum) {
Regex regex = new Regex(#"^[0-9]+$");
return (regex.IsMatch(strNum)) ; } Parsing a string and not using that value is not really needed.
For more details checkout this answers - Regex for numbers only
You could enhance the expression to check the length of the number:
Between 5 and 10 digits:
Regex regex = new Regex(#"^[\d]{5,10}+$");
Max 10 digits:
Regex regex = new Regex(#"^[\d]{10}+$");
At least 5 digits:
Regex regex = new Regex(#"^[\d]{5,}+$");

how to match rules using regex in C#

I am new to regex stuff in C#. I am not sure how to use the regex to validate client reference number. This client reference number has 3 different types : id, mobile number, and serial number.
C#:
string client = "ABC 1234567891233";
//do code stuff here:
if Regex matches 3-4 digits to client, return value = client id
else if Regex matches 8 digts to client, return value = ref no
else if Regex matches 13 digits to client, return value = phone no
I dont know how to count digits using Regex for different types. Like Regex("{![\d.....}").
I don't understand why you're bent on using regular expressions here. A simple one-liner would do, eg. even such an extension method:
static int NumbersCount(this string str)
{
return str.ToCharArray().Where(c => Char.IsNumber(c)).Count();
}
It's clearer and more maintainable in my opinion.
You could probably give it a go with group matching and something along the lines of
"(?<client>[0-9]{5,9}?)|(?<serial>[0-9]{10}?)|(?<mobile>[0-9]{13,}?)"
Then you'd check whether you have a match for "client", "serial", "mobile" and interpret the string input on that basis. But is it easier to understand?
Does it express your intentions more clearly for those reading your code later on?
If the requirement is such that these numbers must be consecutive (as #Corak points out)... I'd still write that iteratively, like so:
/// <summary>
/// returns lengths of all the numeric sequences encountered in the string
/// </summary>
static IEnumerable<int> Lengths(string str)
{
var count = 0;
for (var i = 0; i < str.Length; i++)
{
if (Char.IsNumber(str[i]))
{
count++;
}
if ((!Char.IsNumber(str[i]) || i == str.Length - 1) && count > 0)
{
yield return count;
count = 0;
}
}
}
And then you could simply:
bool IsClientID(string str)
{
var lenghts = Lengths(str);
return lenghts.Count() == 1 && lenghts.Single() == 5;
}
Is it more verbose? Yes, but chances are that people will still like you more than if you make them fiddling with regex every time the validation rules happen to change, or some debugging is required : ) This includes your future self.
I'm not sure if I understood your question. But if you want to get the number of Numerical Characters from a string you can use the following code:
Regex regex = new Regex(#"^[0-9]+$");
string ValidateString = regex.Replace(ValidateString, "");
if(ValidateString.Length > 4 && ValidateString.Length < 10)
//this is a customer id
....

Char tryParse not working as I thought?

I have some problem with a method that I have done in c#. I'm trying to stop user from entering anything else then y and n. It's almost working that I want, but user can still enter more than one sign, and then it doesn't work! How can I do to also check if char is more than one char? I thought the tryParse solved that? Thanks!
// Method to check if item is food or not
private void ReadIfFoodItem()
{
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
if(Char.IsNumber(responseFoodItem))
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
else
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
else
{
Console.WriteLine(errorMessage);
ReadIfFoodItem();
}
}
}
}
The following code "works" in that it produces the expected results.
char responseFoodItem;
Console.Write("Enter if food item or not (y/n): ");
if (char.TryParse(Console.ReadLine(), out responseFoodItem))
{
// Set true or false to variable depending on the response
if ((responseFoodItem == 'y' || responseFoodItem == 'Y'))
{
Console.WriteLine("foodItem = true");
}
else if ((responseFoodItem == 'n' || responseFoodItem == 'N'))
{
Console.WriteLine("foodItem = false");
}
else
{
Console.WriteLine("Unrecognised input");
}
}
else
{
Console.WriteLine("Invalid input");
}
However, has others have pointed out using ReadKey is a better solution if you want to limit the input to a single key. It also means that the user doesn't have to press the Return/Enter key for the input to be accepted.
char represents a single character, so How can I do to also check if char is more than one char? I thought the tryParse solved that? seems a bit nonsensical... TryParse will try and parse a single character from your input and will explicitly fail if the value is null or has a length > 1.
Instead of checking a character, just check the string, e.g.:
string line = Console.ReadLine();
switch (line.ToUpperInvariant())
{
case "Y":
// Do work for y/Y
break;
case "N":
// Do work for n/N
break;
default:
// Show error.
break;
}
char.TryParse simply tries to parse the string supplied as an argument, it does not limit the number of characters that you can input to the console using Console.ReadLine.
When the user inputs more than a single character, char.TryParse will fail because the string returned by Console.ReadLine doesn't contain a single character.
You should use Console.Read instead.
How can I do to also check if char is more than one char?
string line = Console.ReadLIne();
If(!string.IsNullOrEmpty(line) && line.Length > 1)
for reading a single char use Console.ReadChar() instead.
Console.ReadLine allows users to type a string of any length and press enter.
How can I do to also check if char is more than one char? I thought the tryParse solved that?
From the manual page:
Converts the value of the specified string to its equivalent Unicode character. A return code indicates whether the conversion succeeded or failed....The conversion fails if the s parameter is null or the length of s is not 1.
Have you tried using Console.ReadKey instead of ReadLine?
To check it the user has inserted more then one char you could check the string length instead of use Char.TryParse
......
private void ReadIfFoodItem()
{
string answer=string.empty;
Console.Write("Enter if food item or not (y/n): ");
answer=Console.ReadLine()
if (answer.lenght>=1))
{
//error
.......
}
...............
This answer should help you: How can I limit the number of characters for a console input? C#
The console does not limit the user input (well it does, but to 256 characters), nor does char.TryParse which doesn't do anything at all to limit the input length.
You can try using Console.ReadKey
It's just one keystroke for the user and you know there won't be more than one char.
Why not comparing to the input'ed string?
And why not simplifying the comparison?
using System.Linq;
private static string[] ValidAnswers = new string[]{ "y", "yes" };
// Method to check if item is food or not
private void ReadIfFoodItem() {
Console.Write("Enter if food item or not (y/n): ");
string ans = Console.ReadLine();
// Checks if the answer matches any of the valid ones, ignoring case.
if (PositiveAnswers.Any(a => string.Compare(a, ans, true) == 0)) {
foodItem = true;
selectedVATRate = 12; // Extra variable to store type of VAT
} else {
foodItem = false;
selectedVATRate = 25; // Extra variable to store type of VAT
}
}
Alternatively, as others said, you can use Console.ReadKey().
Use Console.ReadKey() to limit the amount of characters. To test whether you have a Y or an N then you can compare the ASCII codes or use a regular expression.

Categories