Regular expression to match one of two characters - c#

What regular expression can I use to make sure input matches either a character 'a' or character 'x'.
I have tried the following but this doesn't work as I had hoped.
char option;
Console.WriteLine("Please make your option");
for (int i = 0; i < options.Length; i++)
{
Console.WriteLine(options[i]);
}
option = char.Parse(Console.ReadLine());
while (option != 'a' || option != 'x')
{
Console.WriteLine("'a' or 'x' please!!");
option = char.Parse(Console.ReadLine());
}
What I want is for one of the two characters to be accepted only...as input.

Regex.IsMatch(input, "[ax]", RegexOptions.IgnoreCase);
will match a,x,A,X

a + x in rational language, (a | x) or [ax] in almost every regexp system.

No regex is needed, you have logic error here, you need to use && (AND) logic operator instead of || (OR) in your while loop:
while (option != 'a' && option != 'x')

Related

A string contains at least one but no more than 2 letters "n" in C# regular expression?

Given a string, how could I write a regular expression that matches when the string contains at least one but no more than 2 letters "n" at any position? So far, I only came up with n{1,2}
http://regexstorm.net/tester
I'd use:
^[^n]*n[^n]*n?[^n]*$
Where [^n]* stands for 0 or more NON n
It will match at least one n and at most 2 n
According to comment, you could use:
^(?:[^n]*n[^n]*){1,2}$
You can change {1,2} into {3,5} or anything you want.
^(?!(?:.*n){3}).*n.*$
You can add a lookahead for the same.See demo.
https://regex101.com/r/cZ0sD2/10
or
^(?!(?:[^\nn]*n){3}).*n.*$
https://regex101.com/r/cZ0sD2/11
Why use Regex at all? This is trival to implement in an extension method that is highly mantainable and flexible.
public static bool ContainsMoreThanAndLessThan(this string s, char c, int maxOcurrences, int minOcurrences)
{
Debug.Assert(maxOcurrences >= minOcurrences);
Debug.Assert(minOcurrences > 0);
Debug.Assert(s != null);
if (s.Length < minOcurrences)
{
return false;
}
var ocurrences = 0;
foreach (var ch in s)
{
if (ch == c)
{
ocurrences++;
}
if (ocurrences > maxOcurrences)
{
return false;
}
}
return ocurrences >= minOcurrences;
}
Another example Regex, adapted from this answer, will give you a match on 1 or two occurrences of the character.
"^([^n]*n){1,2}[^n]*$"
Is there a reason this cannot be solved with a simple method as InBetween suggests?

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*$");

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);
}

Regex to find out if the sequence has any special characters

I am looking for a regex to find out the given word sequence has any special characters.
For example.
In this input string
"test?test";
I would like to find out the words got
"test(any special char(s) including space)test"
You can just use [^A-Za-z0-9], which will match anything that is not alphanumeric, but of course it depends on what you consider a "special character." If underscore is not special [\W] can be a shortcut for anything that is not a word (A-Za-z0-9_) character.
You don't really need a regex here. If you want to test for alphanumeric characters, you car use LINQ, for example (or just iterate over the letters):
string input = "test test";
bool valid = input.All(Char.IsLetterOrDigit);
Char.IsLetterOrDigit checks for all Unicode alphanumeric characters. If you only want the English ones, you can write:
public static bool IsEnglishAlphanumeric(char c)
{
return ((c >= 'a') && (c <= 'z'))
|| ((c >= 'A') && (c <= 'Z'))
|| ((c >= '0') && (c <= '9'));
}
and use it similarly:
bool valid = input.All(IsEnglishAlphanumeric);

what's the quickest way to extract a 5 digit number from a string in c#

what's the quickest way to extract a 5 digit number from a string in c#.
I've got
string.Join(null, System.Text.RegularExpressions.Regex.Split(expression, "[^\\d]"));
Any others?
The regex approach is probably the quickest to implement but not the quickest to run. I compared a simple regex solution to the following manual search code and found that the manual search code is ~2x-2.5x faster for large input strings and up to 4x faster for small strings:
static string Search(string expression)
{
int run = 0;
for (int i = 0; i < expression.Length; i++)
{
char c = expression[i];
if (Char.IsDigit(c))
run++;
else if (run == 5)
return expression.Substring(i - run, run);
else
run = 0;
}
return null;
}
const string pattern = #"\d{5}";
static string NotCached(string expression)
{
return Regex.Match(expression, pattern, RegexOptions.Compiled).Value;
}
static Regex regex = new Regex(pattern, RegexOptions.Compiled);
static string Cached(string expression)
{
return regex.Match(expression).Value;
}
Results for a ~50-char string with a 5-digit string in the middle, over 10^6 iterations, latency per call in microseconds (smaller number is faster):
Simple search: 0.648396us
Cached Regex: 2.1414645us
Non-cached Regex: 3.070116us
Results for a ~40K string with a 5-digit string in the middle over 10^4 iterations, latency per call in microseconds (smaller number is faster):
Simple search: 423.801us
Cached Regex: 1155.3948us
Non-cached Regex: 1220.625us
A little surprising: I would have expected Regex -- which is compiled to IL -- to be comparable to the manual search, at least for very large strings.
Use a regular expression (\d{5}) to find the occurrence(s) of the 5 digit number in the string and use int.Parse or decimal.Parse on the match(s).
In the case where there is only one number in text.
int? value = null;
string pat = #"\d{5}"
Regex r = new Regex(pat);
Match m = r.Match(text);
if (m.Success)
{
value = int.Parse(m.Value);
}
Do you mean convert a string to a number? Or find the first 5 digit string and then make it a number? Either way, you'll probably be using decimal.Parse or int.Parse.
I'm of the opinion that Regular Expressions are the wrong approach. A more efficient approach would simply to walk through the string looking for a digit, and then advancing 4 characters and seeing if they are all digits. If they are, you've got your substring. It's not as robust, no, but it doesn't have the overhead either.
Don't use a regular expression at all. It's way more powerful than you need - and that power is likely to hit performance.
If you can give more details of what you need it to do, we can write the appropriate code... (Test cases would be ideal.)
If the numbers exist with other characters regular expressions are a good solution.
EG: ([0-9]{5})
will match - asdfkki12345afdkjsdl, 12345adfaksk, or akdkfa12345
If you have a simple test case like "12345" or even "12345abcd" don't use regex at all. They are not known by they speed.
For most strings a brute force method is going to be quicker than a RegEx.
A fairly noddy example would be:
string strIWantNumFrom = "qweqwe23qeeq3eqqew9qwer0q";
int num = int.Parse(
string.Join( null, (
from c in strIWantNumFrom.ToCharArray()
where c == '1' || c == '2' || c == '3' || c == '4' || c == '5' ||
c == '6' || c == '7' || c == '8' || c == '9' || c == '0'
select c.ToString()
).ToArray() ) );
No doubt there are much quicker ways, and lots of optimisations that depend on the exact format of your string.
This might be faster...
public static string DigitsOnly(string inVal)
{
char[] newPhon = new char[inVal.Length];
int i = 0;
foreach (char c in inVal)
if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0)
newPhon[i++] = c;
return newPhon.ToString();
}
if you want to limit it to at most five digits, then
public static string DigitsOnly(string inVal)
{
char[] newPhon = new char[inVal.Length];
int i = 0;
foreach (char c in inVal)
if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0 && i < 5)
newPhon[i++] = c;
return newPhon.ToString();
}

Categories