How can I check the format of an E-Mail address? - c#

I am building an e-mail validation program.
How can I check if my E-Mail has 3 letters before the # and 2 letters after the "." I tried else if but it didn't work.
string rightPassword = "red#gmx.to";
string enter = Console.ReadLine();
string red = rightPassword.Substring(0, 3);
string to = rightPassword.Substring(8);
int lengthRed = red.Length;
int lengthTo = to.Length;
do
{
Console.Write("Write the E-Mail: ");
enter = Console.ReadLine();
if (rightPassword == enter)
{
Console.WriteLine("Right Password");
}
else if (lengthRed < 3 ) // I have to check if it has 3 letters before the #//
{
Console.WriteLine("You need 3 letters before the #")
}
else if (lengthTo < 2)
{
Console.WriteLine("You need 2 letter after the ".")
}
} while (enter != "enter");

Just use Regular expressions for pattern matching.
You should use this regex to achieve what you want: ^\w{3}#\w+.\w{2}$
code example:
string email = "abc#aa.co";
Regex regex = new Regex(#"^\w{3}#\w+.\w{2}$");
Match match = regex.Match(email);
if(match.Success)
Console.WriteLine("Email matches pattern");
else Console.WriteLine("Email does not matches pattern");

If you don't want to use Regular Expressions, even though it is highly encouraged, you can add a method:
public static bool HasValidUsername(string email)
{
for (int i = 0; i < 3; i++)
{
if (!email[i].IsLetter())
{
return false;
}
}
return true;
}
And use the method in your code:
else if (!HasValidUsername(enter))
{
Console.WriteLine("You need 3 letters before the #");
}
But keep in mind, that the example above will not validate numbers or symbols. You could use email[i].IsSymbol() or email[i].IsNumber() to check for that.
Note:
x#com is a valid email adress for a domain registrar. That said, most of them use a subdomain for their email. x#x.com for example. Handling all real world email cases is not as trivial as it might seem.

Using Char.IsLetter() method
public bool IsValidEmail(string email)
{
return email.Length > 2 Char.IsLetter(str[0]) && Char.IsLetter(str[1]) && Char.IsLetter(str[2]);
}

You could also use Split.
Something like
string red = rightPassword.Split('#')[0];
string to = rightPassword.Split('.').Last();
you'll also be able to check what's after the "#" if you use
string red = rightPassword.Split('#')[0];
string gmx= rightPassword.Split('#')[1];
string to = rightPassword.Split('.').Last();

Related

C#, Validating user input for letters and whitespace using boolean

I'm making a program that reverses a string and doesn't allow for anything else than letters and whitespaces, problem is that if i enter a non-valid input and then try to input a valid input it just keeps printing error. I think the problem has something to do with my while loop and the bool result, but i can't figure it out. Please help and thank you!
static void Reverse()
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
bool result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$")) // Validates the input for characters and/or spaces
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
while (name == String.Empty || result == false) //Should validate the input for whitespace or letter if it doesn't pass the first validation
{
Console.Write("Error! Enter your name, only letters allowed: ");
name = Console.ReadLine();
}
}
You need to wrap your while loop around the hole sequence instead of just having it inside the else statement.
Example:
static void Reverse()
{
// Continues executing as long as result stays false.
bool result;
do
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$"))
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
Console.WriteLine("Error! Only letters allowed");
}
}
while (!result);
}

Get Expression in Named Capture

I am providing a textbox for one to enter a Regular Expression to match filenames. I plan to detect any named capture groups that they provide with the Regex method GetGroupNames().
I want to get the expression that they entered inside each named capture group.
As an example, they might enter a regular expression like this:
December (?<FileYear>\d{4}) Records\.xlsx
Is there a method or means to get the sub-expression \d{4} apart from manually parsing the regular expression string?
Here is an ugly brute force extension for parsing without using another Regex to detect the subexpression (or subpattern):
public static string GetSubExpression(this Regex pRegex, string pCaptureName)
{
string sRegex = pRegex.ToString();
string sGroupText = #"(?<" + pCaptureName + ">";
int iStartSearchAt = sRegex.IndexOf(sGroupText) + sGroupText.Length;
string sRemainder = sRegex.Substring(iStartSearchAt);
string sThis;
string sPrev = "";
int iOpenParenCount = 0;
int iEnd = 0;
for (int i = 0; i < sRemainder.Length; i++)
{
sThis = sRemainder.Substring(i, 1);
if (sThis == ")" && sPrev != #"\" && iOpenParenCount == 0)
{
iEnd = i;
break;
}
else if (sThis == ")" && sPrev != #"\")
{
iOpenParenCount--;
}
else if (sThis == "(" && sPrev != #"\")
{
iOpenParenCount++;
}
sPrev = sThis;
}
return sRemainder.Substring(0, iEnd);
}
The usage looks like this:
Regex reFromUser = new Regex(txtFromUser.Text);
string[] asGroupNames = reFromUser.GetGroupNames();
int iItsInt;
foreach (string sGroupName in asGroupNames)
{
if (!Int32.TryParse(sGroupName, out iItsInt)) //don't want numbered groups
{
string sSubExpression = reParts.GetSubExpression(sGroupName);
//Do what I need to do with the sub-expression
}
}
Now, if you would like to generate test or sample data, you can use the NuGet package called "Fare" in the following way after you get a sub-expression:
//Generate test data for it
Fare.Xeger X = new Fare.Xeger(sSubExpression);
string sSample = X.Generate();
This pattern (?<=\(\?<\w+\>)([^)]+) will give you all the named match capture expression with the name of the capture. It uses a negative look behind to make sure the text matched will have a (?<...> before it.
string data = #"December (?<FileYear>\d{4}) Records\.xlsx";
string pattern = #"(?<=\(\?<\w+\>)([^)]+)";
Regex.Matches(data, pattern)
.OfType<Match>()
.Select(mt => mt.Groups[0].Value)
returns one item of
\d{4}
While the data such as (?<FileMonth>[^\s]+)\s+(?<FileYear>\d{4}) Records\.xlsx would return two matches:
[^\s]+
\d{4}
Here is a solution using a regular expression to match the capturing groups in a regular expression. Idea is from this post Using RegEx to balance match parenthesis:
\(\?\<(?<MyGroupName>\w+)\>
(?<MyExpression>
((?<BR>\()|(?<-BR>\))|[^()]*)+
)
\)
or more concisely...
\(\?\<(?<MyGroupName>\w+)\>(?<MyExpression>((?<BR>\()|(?<-BR>\))|[^()]*)+)\)
and to use it might look like this:
string sGetCaptures = #"\(\?\<(?<MyGroupName>\w+)\>(?<MyExpression>((?<BR>\()|(?<-BR>\))|[^()]*)+)\)";
MatchCollection MC = Regex.Matches(txtFromUser.Text, sGetCaptures );
foreach (Match M in MC)
{
string sGroupName = M.Groups["MyGroupName"].Value;
string sSubExpression = M.Groups["MyExpression"].Value;
//Do what I need to do with the sub-expression
MessageBox.Show(sGroupName + ":" + sSubExpression);
}
And for the example in the original question, the message box would return FileYear:\d{4}

Validating String in C#

Hi so im trying to validate my string here so that it does not allow any input that starts with: "911" so if you type: "9 11", "91 1", "9 1 1" it should go through my if statement. It works with "911" but not the others, here's my code:
using System;
using System.Collections.Generic;
namespace Phone_List
{
class Program
{
static void Main(string[] args)
{
var phoneList = new List<string>();
string input;
Console.WriteLine("Input: ");
while ((input = Console.ReadLine()) != "")
{
phoneList.Add(input);
for (int i = 0; i < phoneList.Count; i++)
{
if (phoneList[i].Substring(0, 3) == "911")
{
input.StartsWith("9 11");
input.StartsWith("9 1 1");
input.StartsWith("91 1");
Console.WriteLine("NO");
Console.ReadLine();
return;
}
else
{
Console.WriteLine("YES");
Console.ReadLine();
return;
}
}
}
}
}
}
As you can see I am trying to use "input.StartsWith("9 11");" but it does not work...
You could use the Replace method of String; the condition you describe can be formulated as follows.
input.Replace(" ", "").StartsWith("911")
Use regular expressions for checks like this.
For example:
Regex.IsMatch(input, "^\\s*9\\s*1\\s*1");
This regex matches all strings that include whitespaces in front of and between "911".
Use the following to check if the string starts with "911":
First create a copy from the input string but without any white spaces:
string input_without_white_spaces =
new string(input.ToCharArray().Where(x => !char.IsWhiteSpace(x)).ToArray());
Then you can check if the string starts with 911 like this:
if (input_without_white_spaces.StartsWith("911"))
{
...
}
bool valid = s.StartsWith("911") ||
!string.Join("",s.Split()).StartsWith("911");

How do I use regex to validate my string?

I'm trying to use a method to validate a string that has two capital letters at the start and 3 digits after that. The one I am writing at the minute is:
static void Main(string[] args)
{
Console.WriteLine("Enter stock quantity:");
string qty = Console.ReadLine();
string code = enterStockCode();
}
static string enterStockCode()
{
string[] pLetters = new string[] { "BL", "FS", "HJ", "PX" };
bool isValid = false;
while (isValid == false)
{
Console.WriteLine("Enter stockcode:");
string stockCode = Console.ReadLine();
char[] stockCodeSplit = stockCode.ToCharArray();
var vLetters = (stockCodeSplit[0] + stockCodeSplit[1]);
var vNumbers = (stockCodeSplit[2] + stockCodeSplit[3] + kCodeSplit[4]);
// I'd like to know if there is a better way of splitting this string
// by using regular expressions or another way.
foreach (var Letter in pLetters)
{
if (vNumbers.ToString() == Letter)
{
if (Regex.Match(vNumbers.ToString(), #"^\d[0-9]{2}$").Success)
return stockCode;
Console.WriteLine("Invalid stock code");
}
}
}
return "Invalid";
}
(Also I would like to know if the "2" in:
#"^\d[0-9]{2}$"
means 2 times or three times as c# uses index of 0.)
Any help at all is appreciated.
please try:
^[A-Z]{2}\d{3}
If you just want to find an expression starting with 2 capital letters followed by 3 digits you should not put an ending limiter, just the starting.
The 2 means 2 times.

Regex for complex password validation

I looked around on stackoverflow, etc, but haven't found a good answer for this..Does regex support writing a rule like this? If so is there any regex experts our there who can help me write this, I am a big newb to regex and in a time crunch...
I know I can do this with a manual function in c# using c# char, number methods, but I would like to use regex if I can for this..
Requirement :
At least 8 characters long
2 letters
2 digits
1 Upper case
1 Lower case
1 Symbol
You can use this regex
^(?=(.*\d){2})(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z\d]).{8,}$
--------- --------------------- --------------- -----
| | | |->match 8 or more characters
| | |->match further only if theres anything except letter or digit
| |->match further only if there is an upper-lower case letter
|
|->match further only if there are two digits anywhere
Demo
You are much better off writing a simple validation routine for a password that has all of these checks.
A regular expression doesn't seem as the best (or most extensible) solution for this particular problem.
if(password.Length < 8)
return false;
var letters = 0;
var digits = 0;
var uppers = 0;
var lowers = 0;
var symbols = 0;
foreach(var ch in password)
{
if (char.IsLetter(ch)) letters++;
if (char.IsDigit(ch)) digits++;
....
}
if(letters < 2) return false;
...
I recommend going the way Oded's answer did, but I think LINQ is a more readable and explicit validation mechanism in this case.
string p = "psW%Rd32";
return p.Length >= 8 &&
p.Count(c => char.IsDigit(c)) >= 2 &&
p.Count(c => char.IsUpper(c)) >= 1 &&
p.Count(c => char.IsLower(c)) >= 1) ...
You may try this method.
private bool ValidatePassword(string password, out string ErrorMessage)
{
var input = password;
ErrorMessage = string.Empty;
if (string.IsNullOrWhiteSpace(input))
{
throw new Exception("Password should not be empty");
}
var hasNumber = new Regex(#"[0-9]+");
var hasUpperChar = new Regex(#"[A-Z]+");
var hasMiniMaxChars = new Regex(#".{8,8}");
var hasLowerChar = new Regex(#"[a-z]+");
var hasSymbols = new Regex(#"[!##$%^&*()_+=\[{\]};:<>|./?,-]");
if (!hasLowerChar.IsMatch(input))
{
ErrorMessage = "Password should contain At least one lower case letter";
return false;
}
else if (!hasUpperChar.IsMatch(input))
{
ErrorMessage = "Password should contain At least one upper case letter";
return false;
}
else if (!hasMiniMaxChars.IsMatch(input))
{
ErrorMessage = "Password should not be less than or greater than 8 characters";
return false;
}
else if (!hasNumber.IsMatch(input))
{
ErrorMessage = "Password should contain At least one numeric value";
return false;
}
else if (!hasSymbols.IsMatch(input))
{
ErrorMessage = "Password should contain At least one special case characters";
return false;
}
else
{
return true;
}
}

Categories