C# String and Digits Regular Expression - c#

How can I allow the users that can only type 2words that only accepts M and C word and 5 digits number (0-9) ?
For example MC04326
Here is my code so far
else if (!(new Regex(#"^(MC)(([][0-9])$")).IsMatch(txtStudentIDReg.Text))
{
}

No need for regex with such simple validation:
// str is inputted string
var isValid =
str.StartsWith("MC") && // starts with MC
str.Substring(2).All(ch => char.IsDigit(ch)) && // after second character, all are digits
str.Length == 7; // is of length 7

Related

Find 3 or more whitespaces with regex in C# [duplicate]

This question already has answers here:
Regex to validate string for having three non white-space characters
(2 answers)
Closed 3 years ago.
As said above, I want to find 3 or more whitespaces with regex in C#. Currently I tried:
\s{3,} and [ ]{3,} for Somestreet 155/ EG 47. Both didnt worked out. What did I do wrong?
This \s{3,} matches 3 or more whitespace in a row. You need for example this pattern \s.*\s.*\s to match a string with 3 whitespaces anywhere.
So this would match:
a b c d
a b c
a b
abc d e f
a
a b // ends in 1 space
// just 3 spaces
a // ends in 3 spaces
Linq is an alternative way to count spaces:
string source = "Somestreet 155/ EG 47";
bool result = source
.Where(c => c == ' ') // spaces only
.Skip(2) // skip 2 of them
.Any(); // do we have at least 1 more (i.e. 3d space?)
Edit: If you want not just spaces but whitespaces Where should be
...
.Where(c => char.IsWhiteSpace(c))
...
You could count the whitespace matches:
if (Regex.Matches(yourString, #"\s+").Count >= 3) {...}
The + makes sure that consecutive matches to \s only count once, so "Somestreet 155/ EG 47" has three matches but "Somestreet 155/ EG47" only has two.
If the string is long, then it could take more time than necessary to get all the matches then count them. An alternative is to get one match at a time and bail out early if the required number of matches has been met:
static bool MatchesAtLeast(string s, Regex re, int matchCount)
{
bool success = false;
int startPos = 0;
while (!success)
{
Match m = re.Match(s, startPos);
if (m.Success)
{
matchCount--;
success = (matchCount <= 0);
startPos = m.Index + m.Length;
if (startPos > s.Length - 2) { break; }
}
else { break; }
}
return success;
}
static void Main(string[] args)
{
Regex re = new Regex(#"\s+");
string s = "Somestreet 155/ EG\t47";
Console.WriteLine(MatchesAtLeast(s, re, 3)); // outputs True
Console.ReadLine();
}
Try ^\S*\s\S*\s\S*\s\S*$ instead.
\S matches non-whitespace characters, ^ matches beginnning of a string and $ matches end of a string.
Demo

Check if a string contains only letters, digits and underscores

I have to check if a string contains only letters, digits and underscores.
This is how I tried but it doesn't work:
for(int i = 0; i<=snameA.Length-1; i++)
{
validA = validA && (char.IsLetterOrDigit(snameA[i])||snameA[i].Equals("_"));
}
I love Linq for this kind of question:
bool validA = sname.All(c => Char.IsLetterOrDigit(c) || c.Equals('_'));
You are assigning validA every time again, without checking its previous value. Now you always get the value of the last check executed.
You could 'and' the result:
validA &= (char.IsLetterOrDigit(snameA[i]) || snameA[i] == '_');
This would mean you still run all characters, which might be useless if the first check failed. So it is better to simply step out if it fails:
for(int i = 0; i<=snameA.Length-1; i++)
{
validA = (char.IsLetterOrDigit(snameA[i]) || snameA[i] == '_');
if (!validA)
{ break; } // <-- see here
}
Or with LINQ:
validA = snameA.All(c => char.IsLetterOrDigit(c) || c == '_');
you can use regex
Regex regex1 = new Regex(#"^[a-zA-Z0-9_]+$");
if(regex1.IsMatch(snameA))
{
}
I would use a Regex
string pattern = #"^[a-zA-Z0-9\_]+$";
Regex regex = new Regex(pattern);
// Compare a string against the regular expression
return regex.IsMatch(stringToTest);
You could try matching a regular expression. There is a built in type for "letters, digits and underscores", which is "\w".
Regex rgx = new Regex(#"\w*");
rgs.IsMatch(yourString);
If you require 1 or more, then use "\w+".
Further information here: Regex.IsMatch
First, letter is a bit vague term: do you mean a..z and A..Z characters or letter could belong to any alphabet, e.g. а..я and А..Я (Russian, Cyrillic letters). According to your current implementation, you want the second option.
Typical solution with loop is to check until first counter example:
Boolean validA = true; // true - no counter examples so far
// Why for? foreach is much readble here
foreach(Char ch in sname)
// "!= '_'" is more readable than "Equals"; and wants no boxing
if (!char.IsLetterOrDigit(ch) && ! (ch != '_')) {
Boolean validA = false; // counter example (i.e. non-letter/digit symbol found)
break; // <- do not forget this: there's no use to check other characters
}
However you can simplify the code with either Linq:
validA = sname.All(ch => Char.IsLetterOrDigit(ch) || ch == '_');
Or regular expression:
validA = Regex.IsMatch(sname, #"^\w*$");

Validate string based on custom format

I want to validate a string based on a custom format: ___.___ or ___,___, 3 numbers followed by a dot or comma followed by 3 numbers (e.g. 123.456 or 123,456).
Currently, I have following code:
string InputText = "123.456"
bool result, result1, result2;
int test, test2;
result = Int32.TryParse(InputText.Substring(0, 3), out test);
result1 = (InputText[3] == '.' || InputText[3] == ',') ? true : false;
result2 = Int32.TryParse(InputText.Substring(4, 3), out test2);
if (result == false || result1 == false || result2 == false)
{
Console.WriteLine("Error! Wrong format.");
}
This works just fine, however, this seems rather inefficient and unnecessarily complex; is there an alternative to this?
Is there an alternative to this? Yes you can use Regex.IsMatch to do this.
String s = "123.456";
if (!Regex.IsMatch(s, #"^\d{3}[.,]\d{3}$")) {
Console.WriteLine("Error! Wrong format.");
}
Explanation:
^ # the beginning of the string
\d{3} # digits (0-9) (3 times)
[.,] # any character of: '.', ','
\d{3} # digits (0-9) (3 times)
$ # before an optional \n, and the end of the string
Pattern to validate 3 numbers followed by a dot or comma followed by 3 numbers is,
^\d{3}[,.]\d{3}$
DEMO
Aditional to Avinash answer if you want to capture the numbers matching the format you can use the following regex:
\b(\d{3}[.,]\d{3})\b
Working demo

c# Regular expression example

The following are examples of correct input strings:
1,a
2,a,b
3,a,b,c
4,a,b,c,b
and so on...
The first number indicates how many letters follow in the string, and the rest of the letters can be either a,b or c in any order.
Can a regular expression be used to correctly match and capture the first number and each of the letters into groups (and exclude the commas) using Regex.Match?
You don't need Regular Expressions to do this, you could just use LINQ.
string[] split = string.Split('.');
string number = split.First();
string[] letters = split.Skip(1).ToArray();
You can use Split and LINQ methods. First you need to validate the input string:
var parts = input.Split(',');
bool isMatch = parts.Skip(1)
.Count(x => x.Length == 1 &&
char.IsDigit(x[0])) == int.Parse(parts[0]);
if(isMatch)
var digits = parts.Select(int.Parse);
More generally you can write an extension method for that:
public static bool IsMatch(this string source)
{
if (source == null) throw new ArgumentNullException("source");
var parts = source.Split(',');
if (parts.Any())
{
return parts.All(x => x.Length > 0 && x.All(char.IsDigit)) && parts.Skip(1).Count() == int.Parse(parts[0]);
}
return false;
}
This method will match the following strings:
1,4
3,456,123,789
5,12,34,11,78,65
And won't match the following strings:
1,2,3
4,2,1
2,1
1,a
2,1,b

switch statement - validate substrings

the field data has 4 acceptable types of values:
j
47d (where the first one-two characters are between 0 and 80 and third character is d)
9u (where the first one-two characters are between 0 and 80 and third character is u)
3v (where the first character is between 1 and 4 and second character is v).
Otherwise the data should be deemed invalid.
string data = readconsole();
what is the best way of validating this input?
I was considering a combination of .Length and Switch substring checks.
ie.
if (data == "j")
else if (data.substring(1) == "v" && data.substring(0,1) >=1 && data.substring(0,1) <=4)
....
else
writeline("fail");
You can use a regular expression that matches the different kinds of values:
^(j|(\d|[1-7]\d|80)[du]|[1-4]v)$
Example:
if (Regex.IsMatch(data, #"^(j|(\d|[1-7]\d|80)[du]|[1-4]v)$")) ...
Explanation of the regular expression:
^ matches the beginning of string
j matches the literal value "j"
| is the "or" operator
\d matches one digit
[1-7]\d matches "10" - "79"
80 matches "80"
[du] matches either "d" or "u"
[1-4] matches "1" - "4"
v matches "v"
$ matches the end of the string
A regular expression will be the most succinct way to validate such rules.
You can use the regular expression:
^(?:j|(?:[0-7]?[0-9]|80)[du]|[1-4]v)$
Another option is to split by number and letter, and check the results. This is quite longer, but probably easier to maintain in the long run:
public bool IsValid(string s)
{
if (s == "j")
return true;
Match m = Regex.Match(s, #"^(\d+)(\p{L})$");
if (!m.Success)
return false;
char c = m.Groups[2].Value[0];
int number;
if (!Int32.TryParse(m.Groups[1].Value, NumberStyles.Integer,
CultureInfo.CurrentCulture, out number)) //todo: choose culture
return false;
return ((c == 'u' || c == 'd') && number > 0 && number <= 80) ||
(c == 'v' && number >= 1 && number <= 4);
}

Categories