I have a textbox, and I want to validate that it matches the pattern Car Plate = [X]__[####]_[ZZZ].
[X] = One upper case letter
_ = Space
[####] = Four digit number
[ZZZ] = Three upper case letter
Example : A 1234 BCD
How do I set validation to match this in a textbox?
this is my code according sir dimitri
private void isvalidplate(string a)
{
if (a[0] < 'A' && a[0] > 'Z')
{
MessageBox.Show("Car Plate is invalid!");
}
else if (a[1] != ' ' && a[5] != ' ')
{
MessageBox.Show("Car Plate is invalid!");
}
else if (a[2] != Int64.Parse(a) && a[3]!= Int64.Parse(a) && a[4]!= Int64.Parse(a) )
{
MessageBox.Show("Car Plate is invalid!");
}
else if ((a[6] < 'A' && a[6] > 'Z')&&(a[7] < 'A' && a[7] > 'Z')&&(a[8] < 'A' && a[8] > 'Z')&&(a[9] < 'A' && a[9] > 'Z'))
{
MessageBox.Show("Car Plate is invalid!");
}
}
but it show an error that "input String Was Not In A correct Format"
the error is in this line
else if (a[2] != Int64.Parse(a) && a[3]!= Int64.Parse(a) && a[4]!= Int64.Parse(a) )
A common tool used across many languages for string validation and parsing is Regular Expressions (often referred to as regex). Getting used to using them is very handy as a developer. A regex matching what you need looks like:
^[A-Z]\s\d{4}\s[A-Z]{3}$
This site shows your regex in action. In C#, you could test your string using the Regex library:
bool valid = Regex.IsMatch(myTestString, #"^[A-Z]\s\d{4}\s[A-Z]{3}$");
There are tons of resources on learning regex online.
So you have to implement explicit tests:
public static String IsCarPlateValid(String value) {
// we don't accept null or empty strings
if (String.IsNullOrEmpty(value))
return false;
// should contain exactly 11 characters
// letter{1}, space {2}, digit{4}, space{1}, letter{3}
// 1 + 2 + 4 + 1 + 3 == 11
if (value.Length != 11)
return false;
// First character should be in ['A'..'Z'] range;
// if it either less than 'A' or bigger than 'Z', car plate is wrong
if ((value[0] < 'A') || (value[0] > 'Z'))
return false;
//TODO: it's your homework, implement the rest
// All tests passed
return true;
}
To test your implementation you can use regular expression:
Boolean isValid = Regex.IsMatch(carPlate, "^[A-Z]{1} {2}[0-9]{4} {1}[A-Z]{3}$");
with evident meaning: one letter, two spaces, four digits, one space, three letters.
Related
This question was asked recently during interview and i couldn't solve so need some suggestion how can i solve the problem
Declaration: I can not use REGEX or any in-built libraries
***** Problem Statement is as below*********
**matches
Input: text (string), query (string)
Output: true if you can find a match for query within text, false otherwise
If there are no special characters, most languages have a contains method that will just do this.
One special character: '?' -- if you find '?' in the query string, it signals that the previous character is optional (matches 0 or 1 times).
Examples:
No question marks:
matches("hello World", "hello") returns true
matches("hello World", "world") returns false
matches("hello World", "o W")returns true
matches("hello World", "W o") returns false
matches("hello World", "h W") returns false
With question marks -- "l?" means "optional l":
matches("heo World", "hel?o") returns true
matches("helo World", "hel?o") returns true
matches("hello World", "hel?o") returns false
Make sure you understand this case:
matches("hello World", "hell?lo") returns true
You can have more than one question mark:
matches("hello World", "ex?llo Worlds?") returns true
***** My approach was as below*********
public class StringPatternMatch
{
public static bool MatchPattern(string inputText, string pattern)
{
int count = 0; int patternIndex = 0;
for (var i = 0; i < inputText.Length; i++)
{
if (patternIndex > pattern.Length)
break;
if (inputText[i] == pattern[patternIndex] ||
(inputText[i] != pattern[patternIndex] && pattern[patternIndex + 1] == '?'))
count++;
patternIndex++;
}
return pattern.Length == count;
}
}
traverse both strings from one side to other side (say from rightmost character to leftmost). If we find a matching character, we move ahead in both strings with increasing counter for pattern - at the end match count with pattern-length
Also i have provided my code but that doesn't cover all the cases
Of course i didn't go next round, but i am still thinking about this problem and haven't found accurate solution - hope to see some interesting answers!
Your idea can work but your implementation is over-simplified:
// assumes the pattern is valid, e.g. no ??
public static boolean matches(String string, String pattern) {
int p = 0; // position in pattern
// because we only return boolean we can discard all optional characters at the beginning of the pattern
while (p + 1 < pattern.length() && pattern.charAt(p + 1) == '?')
p += 2;
if (p >= pattern.length())
return true;
for (int s = 0; s < string.length(); s++) // s is position in string
// find a valid start position for the first mandatory character in pattern and check if it matches
if (string.charAt(s) == pattern.charAt(p) && matches(string, pattern, s + 1, p + 1))
return true;
return false;
}
private static boolean matches(String string, String pattern, int s, int p) {
if (p >= pattern.length()) // end of pattern reached
return true;
if (s >= string.length() || string.charAt(s) != pattern.charAt(p)) // end of string or no match
// if the next character of the pattern is optional check if the rest matches
return p + 1 < pattern.length() && pattern.charAt(p + 1) == '?' && matches(string, pattern, s, p + 2);
// here we know the characters are matching
if (p + 1 < pattern.length() && pattern.charAt(p + 1) == '?') // if it is an optional character
// check if matching the optional character or skipping it leads to success
return matches(string, pattern, s + 1, p + 2) || matches(string, pattern, s, p + 2);
// the character wasn't optional (but matched as we know from above)
return matches(string, pattern, s + 1, p + 1);
}
I saw a similar topic (this) but could not reach the ideal solution.
What I need:
A mask that works on the keypress event of aTextBox replacing non-numeric and excessive hyphens with "".
Allowing:
What is my difficulty?
Check for the entry of only one hyphen in the same expression.
I got into the solution using substring and it only worked in KeyUP, but I wanted to get through using an expression and keypress event.
What I've already tried:
using System.Text.RegularExpressions;
//trying to denie non-digit and hyphen.
//In conjunction with replace I remove everything that is not hyphen and digit
private static Regex MyMask = new Regex(#"[^\d-]");
private void inputSequential_KeyUp (object sender, KeyEventArgs e)
{
if (! String.IsNullOrEmpty (inputSequential.Text)
{
inputSequential.Text = MyMask.Replace (inputSequential.Text, "");
// MatchCollection matches = Regex.Matches (inputSequential.Text, "[\\ -]");
//
// if (matches.Count> 1)
// {
// for (int i = 1; i <= matches.Count - 1; i ++)
// {
// inputSequential.Text = inputSequential.Text.Substring (0, matches [i] .Index-1) + inputSequential.Text.Substring (matches [i] .Index, inputSequential.Text.Length);
// inputSequential.Text = inputSequential.Text.Replace (inputSequential.Text [matches [i] .Index] .ToString (), "");
//}
//}
}
}
Expected:
If you know better ways to do this please let me know.
Thanks for listening.
You can use a LINQ expression to get only the numbers and one hyphen:
string input = "12-3-47--Unwanted Text";
int hyphenCount = 0;
string output = new string(input.Where(ch => Char.IsNumber(ch) || (ch == '-' && hyphenCount++ < 1)).ToArray());
You seem at lost:
that expression: (:? ) - is not a nonmatched group. The correct variant is : (?: )
digitsOnly - it will be \d?
You should not escape -
If you are looking for a -, simply write it down.
For regex - Better write down in words, what are you looking for. For excluding or for taking in, does not matter, but SAY IN ENGLISH, what do you need.
Please, write down examples that should be accepted and these ones that should NOT be accepted.
For getting only numbers, possibly with - before, use:
-?\d+
tests
I searched here for some alternatives, with Regex or MaskedTextBox (This did not help me much because by default it is not supported in toolStrip where my textBox was).
At the end of the day the best solution I found was dealing with the input of values to each char:
private void inputSequencial_KeyPress(object sender, KeyPressEventArgs e)
{
//Allow only digits(char 48 à 57), hyphen(char 45), backspace(char 8) and delete(char 127)
if ((e.KeyChar >= 48 && e.KeyChar <= 57) || e.KeyChar == 45 || e.KeyChar == 8 || e.KeyChar == 127)
{
switch (e.KeyChar)
{
case (char)45:
int count = inputSequencial.Text.Split('-').Length - 1;
//If the first char is a hyphen or
//a hyphen already exists I reject the entry
if (inputSequencial.Text.Length == 0 || count > 0)
{
e.Handled = true;
}
break;
}
}
else
{
e.Handled = true; //Reject other entries
}
}
private void inputSequencial_KeyUp(object sender, KeyEventArgs e)
{
//if last char is a hyphen i replace it.
if (inputSequencial.Text.Length > 1)
{
string lastChar = inputSequencial.Text.Substring(inputSequencial.Text.Length - 1, 1);
if (lastChar == "-")
{
inputSequencial.Text.Replace("-", "");
}
}
}
You can use this for nondigit [^\d]:
var st = "1kljkj--2323'sdfkjasdf2";
var result = Regex.Replace(st, #"^(\d).*?(-)[^\d]*(\d+)[^\d]*", #"$1$2$3");
1-23232
I have this string coming from a virtual serial port with an ID/Passport reader:
b\0OU0IDBGR9247884874<<<<<<<<<<<<<<<|8601130M1709193BGR8601138634<3|IVANOV<
I have replaced the "/r" with "|" character.
The problem I would like to solve is always remove the characters before reaching the first combination of characters in the string which might be:
"ID","I<","P<" & "V<" "VI".
This is the issue at this stage I have tried the following to remove the characters but with no success:
public static string RemoveSpecialCharacters(string str)
{
StringBuilder sb = new StringBuilder();
foreach (char c in str)
{
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '_' || c == '<' )
{
sb.Append(c);
}
}
return sb.ToString();
}
Remove the characters before reaching the first combination of characters in the string which might be: "ID","I<","P<" & "V<" "VI".
I think will do what you want.
string s = "b\0OU0IDBGR9247884874<<<<<<<<<<<<<<<|8601130M1709193BGR8601138634<3|IVANOV<";
s = string.Join("", Regex.Split(s, "(ID|I<|P<|V<|VI)").Skip(1));
First it splits the string on the character combinations you wanted (While preserving them in the resulting array - see the regex character group) and then discards the first member of the array (Which will be all the characters before the character combinations.) Then it joins the array together.
I am using .net 4.5 and
HttpUtility.HtmlDecode fails to decode ' which is single quote character
Any idea why ?
Using C# .net 4.5 WPF on windows 8.1
Here the text that is failed
Apple 13'' Z0RA30256 MacBook Pro Retina
Below is framework version
#region Assembly System.Web.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll
#endregion
It's not possible to handle this with the built it HtmlDecode method, you would have to find/replace it or otherwise work around.
Below is the source code for HtmlDecode - you can see from the comment explicitly that your scenario is considered and not supported - HTML entities have to be bounded with a ;, otherwise they are simply not HTML entities. Browsers are forgiving of the incorrect markup, and compensate accordingly.
// We found a '&'. Now look for the next ';' or '&'. The idea is that
// if we find another '&' before finding a ';', then this is not an entity,
// and the next '&' might start a real entity (VSWhidbey 275184)
Here is the full source of the .NET HtmlDecode in HttpUtility, if you want to adapt the behaviour.
http://referencesource.microsoft.com/#System/net/System/Net/WebUtility.cs,44d08941e6aeb00d
public static void HtmlDecode(string value, TextWriter output)
{
if (value == null)
{
return;
}
if (output == null)
{
throw new ArgumentNullException("output");
}
if (value.IndexOf('&') < 0)
{
output.Write(value); // good as is
return;
}
int l = value.Length;
for (int i = 0; i < l; i++)
{
char ch = value[i];
if (ch == '&')
{
// We found a '&'. Now look for the next ';' or '&'. The idea is that
// if we find another '&' before finding a ';', then this is not an entity,
// and the next '&' might start a real entity (VSWhidbey 275184)
int index = value.IndexOfAny(_htmlEntityEndingChars, i + 1);
if (index > 0 && value[index] == ';')
{
string entity = value.Substring(i + 1, index - i - 1);
if (entity.Length > 1 && entity[0] == '#')
{
// The # syntax can be in decimal or hex, e.g.
// å --> decimal
// å --> same char in hex
// See http://www.w3.org/TR/REC-html40/charset.html#entities
ushort parsed;
if (entity[1] == 'x' || entity[1] == 'X')
{
UInt16.TryParse(entity.Substring(2), NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out parsed);
}
else
{
UInt16.TryParse(entity.Substring(1), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out parsed);
}
if (parsed != 0)
{
ch = (char)parsed;
i = index; // already looked at everything until semicolon
}
}
else
{
i = index; // already looked at everything until semicolon
char entityChar = HtmlEntities.Lookup(entity);
if (entityChar != (char)0)
{
ch = entityChar;
}
else
{
output.Write('&');
output.Write(entity);
output.Write(';');
continue;
}
}
}
}
output.Write(ch);
}
}
my program should print a message on the screen if the formula that the user entered is good for the terms(you can only use digits and letters, u can't start with '(' and like mathematical formula, for each open bracket, has to be a suitable(and in the right place) close bracket.
here some formulas that the program should accepts and prints:
True-
a(aa(a)aaa(aa(a)aa)aa)aaaaa
a(((())))
here some formulas that the program should not accepts and prints:
False-
()()()
)()()(
but the program always prints False
thanks for helping
Heres the code:EDIT
bool IsNumeric(char character)
{
return "0123456789".Contains(character);
// or return Char.IsNumber(character);
}
bool IsLetter(char character)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXWZabcdefghigjklmnopqrstuvwxyz".Contains(character);
}
bool IsRecognized(char character)
{
return IsBracket(character) | IsNumeric(character) | IsLetter(character);
}
public bool IsValidInput(string input)
{
if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
{
return false;
}
var bracketsCounter = 0;
for (var i = 0; i < input.Length; i++)
{
var character = input[i];
if (!IsRecognized(character))
{
return false;
}
if (IsBracket(character))
{
if (character == '(')
bracketsCounter++;
if (character == ')')
bracketsCounter--;
}
}
if (bracketsCounter > 0)
{
return false;
}
return bracketsCounter==0;
}
}
}
Your algorithm is unnecessarily complex - all you need is a loop and a counter.
Check the initial character for ( (you already do that)
Set the counter to zero, and go through each character one by one
If the character is not a letter or a parentheses, return false
If the character is an opening (, increment the counter
If the character is a closing ), decrement the counter; if the counter is less than zero, return false
Return true if the count is zero after the loop has ended; otherwise return false
Is debugging this hard really? This condition:
((!IsNumeric(st[i])) && (st[i] != '(') && (st[i] != ')')&&((st[i]<'a')||(st[i]>'z')||(st[i]<'A')||(st[i]>'Z')))
return false;
is obviously wrong. It returns false for a every time. You don't take into consideration that a is greater than Z.
EDIT:
so how can i make it easier to read? that the only way i figured. do u
have other solution for this problem?
As for that condition block - use smaller methods / functions, for example.
bool IsBracket(char character)
{
return (character == '(' | character == ')');
}
bool IsNumeric(char character)
{
return "0123456789".Contains(character);
// or return Char.IsNumber(character);
}
bool IsLetter(char character)
{
// see why this is NOT prone to fail just because 'a' is greater than 'Z' in C#?
return (character >= 'a' & character <= 'z') |
(character >= 'A' & character <= 'Z');
// or return Regex.IsMatch(character.ToString(), "[a-zA-Z]", RegexOptions.None);
// or return Char.IsLetter(character);
}
// now you can implement:
bool IsRecognized(char character)
{
return IsBracket(character) | IsNumeric(character) | IsLetter(character);
}
and then in your big method you could just safely use:
if (!IsRecognized(st[i]))
return false;
It may look like an overkill for such a trivial example, but it's a better approach in principle, and certainly more readable.
And after that, you could reduce your code to something along the lines of:
bool IsInputValid(string input)
{
if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
{
return false;
}
var bracketsCounter = 0;
for (var i = 0; i < input.Length; i++)
{
var character = input[i];
if (!IsRecognized(character))
{
return false;
}
if (IsBracket(character)) // redundant?
{
if (character == '(') // then what?
if (character == ')') // then what?
}
if (bracketsCounter < what?)
{
what?
}
}
return bracketsCounter == what?;
}
(dasblinkenlight's algorithm)
EDIT 10th April
You got it wrong.
bool IsNumeric(char character)
{
return "0123456789".Contains(character);
// or return Char.IsNumber(character);
}
bool IsLetter(char character)
{
return "ABCDEFGHIJKLMNOPQRSTUVWXWZabcdefghigjklmnopqrstuvwxyz".Contains(character);
}
bool IsRecognized(char character)
{
return IsBracket(character) | IsNumeric(character) | IsLetter(character);
}
public bool IsValidInput(string input)
{
if (String.IsNullOrEmpty(input) || IsBracket(input[0]))
{
return false;
}
var bracketsCounter = 0;
for (var i = 0; i < input.Length; i++)
{
var character = input[i];
if (!IsRecognized(character))
{
return false;
}
if (IsBracket(character))
{
if (character == '(')
bracketsCounter++;
if (character == ')')
bracketsCounter--;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (bracketsCounter < 0) // NOT "> 0", and HERE - INSIDE the for loop
{
return false;
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
return bracketsCounter==0;
}
}
}
By the way, you also made a mistake in your IsLetter method:
...UVWXWZ? Should be UVWXYZ