Regex mask with replace for digits and only one hyphen C# - c#

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

Related

Input only digits and control buttons

I want to input Salary with any value: 550,49, 2222,12, 9,3 and so on. But need to use control button like this: ,, backspace, ctrl + c, ctrl + v, ctrl + a.
Salary is TextBox with ShortcutsEnabled = true and event:
private void TbSalary_KeyPress(object sender, KeyPressEventArgs e)
{
char number = e.KeyChar;
if ((e.KeyChar <= 47 || e.KeyChar >= 58) && number != 8 && number != 44)
//digits, BackSpace and ,
{
e.Handled = true;
}
}
If remove this condition, the specified combinations will work. But not only numbers are entered.
Should I add tracking of all combinations here? Or is it possible to implement this task in another way?
MaskedTextBox requires a fixed number of characters with some "mask". But the Salary is different. Can be **,**, ******,* or *** and etc.
UPDATE
Prevent entering more than two numbers after the decimal point
if (number < ' ')
{
return;
}
if (number >= '0' && number <= '9')
{
if (this.Text.Contains(',')
&& this.SelectionLength == 0
&& this.SelectionStart > this.Text.IndexOf(',')
&& this.Text.Length - this.Text.IndexOf(',') > 2)
{
e.Handled = true;
}
return;
}
Please, don't use magic numbers like 47, let's work with characters. We should allow these characters:
'0'..'9' range (numbers)
control characters (which are below space ' ') for tab, backspace etc.
',' (comma) as a decimal separator
All the other characters should be banned.
Code:
private void TbSalary_KeyPress(object sender, KeyPressEventArgs e)
{
char number = e.KeyChar;
TextBox box = sender as TextBox;
if (number >= '0' && number <= '9' || number < ' ')
return; // numbers as well as backspaces, tabs: business as usual
else if (number == ',') {
// We don't want to allow several commas, right?
int p = box.Text.IndexOf(',');
// So if we have a comma already...
if (p >= 0) {
// ... we don't add another one
e.Handled = true;
// but place caret after the comma position
box.SelectionStart = p + 1;
box.SelectionLength = 0;
}
else if (box.SelectionStart == 0) {
// if we don't have comma and we try to add comma at the 1st position
e.Handled = true;
// let's add it as "0,"
box.Text = "0," + box.Text.Substring(box.SelectionLength);
box.SelectionStart = 2;
}
}
else
e.Handled = true; // all the other characters (like '+', 'p') are banned
}
Please, note, that there is possibility to Paste incorrect value (say, "bla-bla-bla") into TbSalary TextBox; to prevent it you can use TextChanged event:
private void TbSalary_TextChanged(object sender, EventArgs e) {
TextBox box = sender as TextBox;
StringBuilder sb = new StringBuilder();
bool hasComma = false;
foreach (var c in box.Text)
if (c >= '0' && c <= '9')
sb.Append(c);
else if (c == ',' && !hasComma) {
hasComma = true;
if (sb.Length <= 0) // we don't start from comma
sb.Append('0');
sb.Append(c);
}
string text = sb.ToString();
if (!text.Equals(box.Text))
box.Text = text;
}

I want make some validation string that match the format below

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.

C# Masked TextBox with 0 or decimals

Users have a textbox where they have to either enter a 0 or a value from 0.0001 to 0.9999.
What regex can I use here? I have looked at other examples but don't see anything like this one.
I'd say this is quite an effective solution. It allows for any strings entered that is either just a '0' or strings with '0.' followed by up to 4 of any digit.
Regex myRegex = new Regex("^(?:(?:0)|(?:0.[0-9]{1,4}))$");
Console.WriteLine("Regex: " + myRegex + "\n\nEnter test input.");
while (true)
{
string input = Console.ReadLine();
if (myRegex.IsMatch(input))
{
Console.WriteLine(input + " is a match.");
}
else
{
Console.WriteLine(input + " isn't a match.");
}
}
Here's a list of tests...
Try this one:
/(0)+(.)+([0-9])/g
Also see thing link that might helps you build you won expreession.
http://regexr.com/
Try this, it will do the work but I was not tested for all cases.
Regex _regex = new Regex("^[0]+(.[0-9]{1,4})?$");
if (input == "0" || _regex.IsMatch(input))
{
//Match
}
else
{
//Does not match
}
Note: input is a string, in your case Textbox.Text!
This is ready to use KeyPress event handler of TextBox control. It will prevent any input, except numeric between 0.0001 and 0.9999:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
//Only one dot is possible
if ((sender as TextBox).Text.Contains('.') && (e.KeyChar == '.')) e.Handled = true;
//Only numeric keys are acceptable
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.')) e.Handled = true;
//Only one zero in front is acceptable, next has to be dot
if (((sender as TextBox).Text == "0") && (e.KeyChar == '0')) e.Handled = true;
double value = 0;
string inputValue = (sender as TextBox).Text + e.KeyChar;
if ((sender as TextBox).Text.Length > 0)
{
//Just in case parse input text into double
if (double.TryParse(inputValue, out value))
{
//Check if value is between 0.0001 and 0.9999
if (value > 0.9999) e.Handled = true;
if (((sender as TextBox).Text.Length > 4) && (value < 0.0001)) e.Handled = true;
}
}
else if (e.KeyChar != '0')
{
e.Handled = true;
}
}

How to prevent the first character to be a number

I have a textbox control and allowing the user to enter only letters or numbers:
private void tbTableName_TextChanged(object sender, EventArgs e)
{
tbTableName.Text = string.Concat(tbTableName.Text.Where(char.IsLetterOrDigit));
if (tbTableName.Text.Length > 0)
{
btnConvert.Enabled = true;
}
else
{
btnConvert.Enabled = false;
}
}
How can I modify so that the first character cannot be a digit, only letter and then they can add as many digit as they want?
I have a WinForm, not a Web Form.
You just need to modify this line:
if (tbTableName.Text.Length > 0)
to:
if (tbTableName.Text.Length > 0 && !Char.IsDigit(tbTableName.Text[0]))
Why not using regular expression?
I edit the regular expression to allow user to add digit or letter after the first digit
btnConvert.Enabled = System.Text.RegularExpressions.Regex.IsMatch(input, "^[a-zA-Z][a-zA-Z0-9 ]+$");
private void tbTableName_TextChanged(object sender, EventArgs e)
{
string name = Regex.Replace(tbTableName.Text, #"^\d+|\W", string.Empty);
btnConvert.Enabled = name.Length > 0;
tbTableName.Text = name;
}
You could just remove the first character if it's a number:
if (tbTableName.Text.Length > 0 && char.IsNumber(tbTableName.Text[0]))
tbTableName.Text = tbTableName.Text.Substring(1);

how to currency format under textbox?

I want enter number in textbox, an my textbox convert automatically it in comma(,) format. I have tried to do this, but it works wrong. Help me? Like this 1,20(I JUST ENTER 120);
private bool IsNumeric(int Val)
{
return ((Val >= 48 && Val <= 57) || (Val == 8) || (Val == 46));
}
String str;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
int KeyCode = e.KeyValue;
if (!IsNumeric(KeyCode))
{
if (KeyCode == 13)
{
e.Handled = true;
vendas();
str = null;
}
e.Handled = true;
return;
}
else
{
e.Handled = true;
}
if (((KeyCode == 8) || (KeyCode == 46)) && (str.Length > 0))
{
str = str.Substring(0, str.Length - 1);
}
else if (!((KeyCode == 8) || (KeyCode == 46)))
{
str = str + Convert.ToChar(KeyCode);
}
if (str.Length == 0)
{
textBox1.Text = "";
}
if (str.Length == 1)
{
textBox1.Text = "0,0" + str;
}
else if (str.Length == 2)
{
textBox1.Text = "0," + str;
}
else if ((str.Length > 2) && (str.Length != 6) && (str.Length != 9) && (str.Length != 12))
{
textBox1.Text = str.Substring(0, str.Length - 2) + "," + str.Substring(str.Length - 2);
textBox1.Text = textBox1.Text;
}
else if ((str.Length > 6) && (str.Length != 8) && (str.Length != 10) && (str.Length != 12))
{
textBox1.Text = str.Substring(0, str.Length - 3) + "," + str.Substring(str.Length - 1);
textBox1.Text = textBox1.Text;
}
}
It shows me 10,01 instead 0,01?
What you want is a MaskedTextBox.
Simply set of mask of "$999,999,990.00" and any input the user enters must be digits, and there must be at least 3, but the entry can be any number up to the hundreds of millions (if you need billions and trillions, just add more 9s and commas). As the user enters these digits, the formatting will adjust based on the mask. Here's the kicker; MaskedTextBox respects culture information, so if you specify the French culture, the commas become spaces, the decimal becomes a comma, and the dollar sign becomes the Euro symbol.
I was originally going to suggest MaskedTextBox, but MTB is designed for left-to-right style formatting of a fixed (or known in advanced, at least) length string, which makes it not so suitable for currency.
First, I'd recommend you avoid doing anything using keycodes or the like, and stick to something a bit more straightforward by just validating and editing the text when it changes:
void tb_TextChanged(object sender, EventArgs e)
{
//Remove previous formatting, or the decimal check will fail
string value = tb.Text.Replace(",", "").Replace("$", "");
decimal ul;
//Check we are indeed handling a number
if (decimal.TryParse(value, out ul))
{
//Unsub the event so we don't enter a loop
tb.TextChanged -= tb_TextChanged;
//Format the text as currency
tb.Text = string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul);
tb.TextChanged += tb_TextChanged;
}
}
The main part is string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul); the en-US ensures it'll always show $ and decmials as '.'s. The {0:C2} formats the string as a number (0) of currency (:C) to 2 decimal spaces (2).
This doesn't prevent the user from entering text, but you can keep the previous text (eg '$23.00') and if the user enters something that isn't a number, decimal.TryParse will fail, at which point you can revert the text back to what it was before the user changed it (just by inserting an else block near the end of this event handler).
I'd recommend setting the TB text to '$0.00' or something initially, or the cursor will jump when it formats the first change. It also has some selection issues when commas are adding, which you could get around by storing the selection position just before formatting and changing it afterward, or doing something more complex, it's just an example.
Well, at first glance, I notice that nothing about your code whatsoever makes any sense.
First and foremost, learn coding standards for indentation. This code is extremely hard to read. I'm tempted to flag this question as offensive for having had to look at it.
Next, this line:
if (!IsNumeric(KeyCode){
Says: if the keycode is NOT numeric do the following stuff, where "the following stuff" is a whole bunch of numeric operations on a keycode which is presumed to be numeric.
Next, str is not defined anywhere in your method. Maybe it's defined globally, but that would just be silly. Rather, you should just get the current value of it programmatically.
And finally:
you don't need to reinvent the wheel. There are tons of tools out there that will do this kind of thing for you. In fact, I'm fairly sure win forms has a native control that'll do this. It might even be an attribute of textbox, I don't remember.

Categories