How to give regular expression for Regex.ismatch function? - c#

I am trying to write a regular expression for accepting a Number of length upto 14 and if they keep the decimal point then it should accept only 2 numbers after the decimal point.
I have tried it from this link below :
https://stackoverflow.com/a/9967694/861995
But, the same Regex.IsMatch function is not accepting the normal regex expression's starting with ^ and ending with $.
Please help me on this i am new to regular expressions
private void ChangedSellUp_KeyDown(object sender, KeyEventArgs e)
{
string pattern = "^[0-9]*$";
Regex rx = new Regex(pattern);
if (rx.IsMatch(ChangedSellUp.Text))
{
e.Handled = true;
}
}
Here ChangedSellup.Text is my text box value, i am trying to restrict the value based on 2 conditions
Its Should Accept only Numbers and length should not increase 14 till Decimal Point.
If decimal Point is there after that only 2 numbers are allowed.
e.g ; valid Values - 14.23, 12345678901234.23
Invalid values - 1.2344, 12345678901234.3455
Please help me with the regex ??

The best way to build regular expressions is with a Regex Tester. There's a really good one you can download called Cappucino, or you can use a web one, I favour http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx
Then it is simply a case of building the regex, I'm testing against 12345678901234.00
If you start with \d which is the regex pattern for a numeric digit then you get all sixteen matches you would expect.
Add a + which is short for one or more, so \d+ matches twice 12345678901234 and 00
If you limit to a range of only two digits i.e. \d{2} then you get 8 pairs of numbers
To add a . you need to escape the character as . is a pattern to match any digit, so instead use \.\d{2} to match only .00 (which was your optional part of the number)
If you pattern match a range of digits between 1 and 14 long \d{1,14} then you will match 12345678901234 (which is the main number) and 00
So now you can put it together, we make the post decimal point part optional by saying we want it either 0 or 1 times {0,1} or with a shorthand variant ? to give
\d{1,14}(\.\d{2})?
which matches correctly on these
12345678901234.00
123456.00
1
1234
and because I'm not matching the start and end of the line, also matches on these
500.00USD
$1000

Here's the Regex.IsMatch that does what you want:
Regex.IsMatch("12345678901234.12", #"^\d{1,14}(?:\.\d{1,2}){0,1}$")
That particular regex is for a number up to 14 digits before the decimal point and 1 or 2 digits after the decimal point (with the whole decimal part being optional)
A good place to test it is here: http://regexhero.net/tester/
Because you've mentioned ^ and $, I've included them in the regex, which will only parse lines with just the number (so, for example " 1234.12 " won't return true in the IsMatch, just remove the "^" and "$" if that is not important).
Another good resource for regex is this: http://www.mikesdotnetting.com/Article/46/CSharp-Regular-Expressions-Cheat-Sheet
UPDATE:
Since the goal is that the user cannot write anything other than something that satisfies that Regex in a textbox you can do this in the text changed event (key down is not a good option since you'd have to deal with converting KeyEventArg's Key to a char). So the easiest way to achieve what you need is:
private void TextBox1_TextChanged(object sender, TextChangedEventArgs e)
{
if (!Regex.IsMatch(TextBox1.Text, #"^\d{1,14}(?:\.\d{0,2}){0,1}$"))
{
TextBox1.Text = TextBox1.Text.Substring(0, TextBox1.Text.Length - e.Changes.Last().AddedLength);
TextBox1.CaretIndex = TextBox1.Text.Length;
}
}
Please notice the slight change in the regular expression that will accept a number followed by a dot, with no extra digits, this is because as you are writing a number with decimal places you'll be in a state where this happens, for example: "123."

Related

Decimal and only positive numeric values

What regex i can use for positive numeric and decimal values ?
Accepted values: 0, 22.5 , 0.35 , 89 , .38
Invalid values : -22 , -.25 , -0.66 , abc, -22abc, 55er
I have tried this but i get error
^\d*\.?\d*[1-9]+\d*$)|(^[1-9]+\d*\.\d*$"
Too many )'s
^\d*\.?\d*[1-9]+\d*$)|(^[1-9]+\d*\.\d*$
You're missing a closing ) in the regex.
^\d*\.?\d*[1-9]+\d*$)|(^[1-9]+\d*\.\d*)$
However, I'd strongly suggest you look at Decimal.TryParse instead of trying to validate numbers using the format of a string yourself.
I would simply your pattern to this:
\d*(?:\.\d+)?
Demo
This seems to cover all your positive decimal number use cases. The decimal component is optional, meaning that the pattern covers integers. Decimal numbers are covered, and also numbers which only have a decimal component.
Note that you might have to surround the pattern with ^$ anchors, depending on the particular API you are using.
Edit:
If you also need to ensure that empty string is not matched, then we can add a lookahead to the above pattern:
(?=.)\d*(?:\.\d+)?
Demo
Or, if you want to stay away from Regex, one of these might work:
private static bool IsPositiveDecimal(string decimalString)
{
return decimal.TryParse(decimalString, out var aDecimal) && aDecimal >= 0;
}
or
private static bool TryParsePositiveDecimal(string decimalString, out decimal aDecimal)
{
return decimal.TryParse(decimalString, out aDecimal) && aDecimal >= 0;
}
If you feed the latter one a non-positive decimal, it will return false, but will return the parsed decimal in the out parameter.
This should suit your needs without injecting a complicated Regex into your code.
I believe this regex should meet all the cases and will only match valid samples and discard all invalid ones.
^(?:[1-9]\d*(\.\d+)?|0?\.\d+|0)$
Regex Explanation:
^ - Start of string
(?: - Start of non capture group
[1-9]\d* - Matches a number without unneeded preceding zeroes. Will invalidated 01 or 001
(\.\d+)? - Can optionally have decimal part
| - Alternation
0?\.\d+ - Allows only decimal numbers that can optionally have zero before them. E.g. to support numbers like 0.11 or .11
| - Alternation
0 - Supporting literal zero as a special case
) - closing of non-capture group
$ - End of string
Demo
^\d*\.?\d+$
There will also match 0.00 .00 0.0

Regular Expressions C#

I know there are many questions about making regular expressions, but they all seem to be about a single problem than the general usage. I, too, have a problem like to solve. I have tried to learn by reading about regular expressions, but it gets tricky quick. Here's my question:
C#
I need to validate two textboxes that exist on the same form. The math operations I've coded can handle any floating point number. For this particular application I know of three formats the numbers will be in or there is a mistake on the users behalf. I'd like to prevent those mistakes in example if an extra number is accidentally typed or if enter is hit too early, etc.
Here are the formats: "#.####" "##.####" "###.##" where the "#" represents a mandatory digit. The formats starting with a one or two digit whole number must have 4 trailing digits or more. I've capped it at 8, or so I tried to lol.The format starting with a three digit whole number should never be allowed to have more than two digits trailing the decimal.
Here's what I have tried thus far.
Regex acceptedInputRegex = new Regex(#"^\b[0-9]{3}.[0-9]{2}|[0-9]{1,2}.[0-9]{4,8}$");
Regex acceptedInputRegex = new Regex(#"^\b\d{3}.\d{2} | \d{1,2}.\d{4,8}$");
I have tried it in thinking a match was what I wanted to achieve and as if a match to my negated expression means there is a problem. I was unsuccessful in both attempts. This is the code:
if (acceptedInputRegex.IsMatch(txtMyTextBox1.Text) || acceptedInputRegex.IsMatch(txtMyTextBox2.Text))
{
} else
{
MessageBox.Show("Numbers are not in the right format", "Invalid Input!");
return;
}
Are regular expressions what I should be using to solve this problem?
If not, please tell me what you recommend. If so, please help me correct my regex.
Thanks.
You are close, you need to escape the dots and group the alternatives so that the ^ and $ anchors could be applied to both of them:
#"^(?:\d{3}\.\d{2}|\d{1,2}\.\d{4,8})$"
See the regex demo.
Details:
^ - start of string
(?: - start of a non-capturing group matching either of the two alternatives:
\d{3}\.\d{2} - 3 digits, . and 2 digits
| - or
\d{1,2}\.\d{4,8} - 1 or 2 digits, ., 4 to 8 digits
) - end of the non-capturing group
$ - end of string.
To make \d match only ASCII digits, use RegexOptions.ECMAScript option:
var isValid = Regex.IsMatch(s, #"^(?:\d{3}\.\d{2}|\d{1,2}\.\d{4,8})$", RegexOptions.ECMAScript);

Regex to ensure that in a string such as "05123:12315", the first number is less than the second?

I must have strings in the format x:y where x and y have to be five digits (zero padded) and x <= y.
Example:
00515:02152
What Regex will match this format?
If possible, please explain the solution briefly to help me learn.
EDIT: Why do I need Regex? I've written a generic tool that takes input and validates it according to a configuration file. An unexpected requirement popped up that would require me to validate a string in the format I've shown (using the configuration file). I was hoping to solve this problem using the existing configuration framework I've coded up, as splitting and parsing would be out of the scope of this tool. For an outstanding requirement such as this, I don't mind having some unorthodox/messy regex, as long as it's not 10000 lines long. Any intelligent solutions using Regex are appreciated! Thanks.
Description
This expression will validate that the first 5 digit number is smaller then the second 5 digit number where zero padded 5 digit numbers are in a : delimited string and is formatted as 01234:23456.
^
(?:
(?=0....:[1-9]|1....:[2-9]|2....:[3-9]|3....:[4-9]|4....:[5-9]|5....:[6-9]|6....:[7-9]|7....:[8-9]|8....:[9])
|(?=(.)(?:0...:\1[1-9]|1...:\1[2-9]|2...:\1[3-9]|3...:\1[4-9]|4...:\1[5-9]|5...:\1[6-9]|6...:\1[7-9]|7...:\1[8-9]|8...:\1[9]))
|(?=(..)(?:0..:\2[1-9]|1..:\2[2-9]|2..:\2[3-9]|3..:\2[4-9]|4..:\2[5-9]|5..:\2[6-9]|6..:\2[7-9]|7..:\2[8-9]|8..:\2[9]))
|(?=(...)(?:0.:\3[1-9]|1.:\3[2-9]|2.:\3[3-9]|3.:\3[4-9]|4.:\3[5-9]|5.:\3[6-9]|6.:\3[7-9]|7.:\3[8-9]|8.:\3[9]))
|(?=(....)(?:0:\4[1-9]|1:\4[2-9]|2:\4[3-9]|3:\4[4-9]|4:\4[5-9]|5:\4[6-9]|6:\4[7-9]|7:\4[8-9]|8:\4[9]))
)
\d{5}:\d{5}$
Live demo: http://www.rubular.com/r/w1QLZhNoEa
Note that this is using the x option to ignore all white space and allow comments, if you use this without x then the expression will need to be all on one line
The language you want to recognize is finite, so the easiest thing to do is just list all the cases separated by "or". The regexp you want is:
(00000:[00000|00001| ... 99999])| ... |(99998:[99998|99999])|(99999:99999)
That regexp will be several billion characters long and take quite some time to execute, but it is what you asked for: a regular expression that matches the stated language.
Obviously that's impractical. Now is it clear why regular expressions are the wrong tool for this job? Use a regular expression to match 5 digits - colon - five digits, and then once you know you have that, split up the string and convert the two sets of digits to integers that you can compare.
x <= y.
Well, you are using wrong tool. Really, regex can't help you here. Or even if you get a solution, that will be too complex, and will be too difficult to expand.
Regex is a text-processing tool to match pattern in regular languages. It is very weak when it comes to semantics. It cannot identify meaning in the given string. Like in your given condition, to conform to x <= y condition, you need to have the knowledge of their numerical values.
For e.g., it can match digits in a sequence, or a mix of digits and characters, but what it cannot do is the stuff like -
match a number greater than 15 and less than 1245, or
match a pattern which is a date between given two dates.
So, where-ever matching a pattern, involves applying semantics to the matched string, Regex is not an option there.
The appropriate way here would be to split the string on colon, and then compare numbers. For leading zero, you can find some workaround.
You can't generally* do this with regex. You can use regex to match the pattern and extract the numbers, then compare the numbers in your code.
For example to match such format (without comparing the numbers) and get the numbers you could use:
^(\d{5}):(\d{5})\z
*) You probably could in this case (as the numbers are always 5 digits and zero padded, but it wouldn't be nice.
You should do something like this instead:
bool IsCorrect(string s)
{
string[] split = s.split(':');
int number1, number2;
if (split.Length == 2 && split[0].Length == 5 && split[1].Length == 5)
{
if (int.TryParse(split[0], out number1) && int.TryParse(split[1], out number2) && number1 <= number2)
{
return true;
}
}
return false;
}
With regex you can't make comparisons to see if a number is bigger than another number.
Let me show you a good example of why you shouldn't try to do this. This is a regex that (nearly) does the same job.
https://gist.github.com/anonymous/ad74e73f0350535d09c1
Raw file:
https://gist.github.com/anonymous/ad74e73f0350535d09c1/raw/03ea835b0e7bf7ac3c5fb6f9c7e934b83fb09d95/gistfile1.txt
Except it's just for 3 digits. For 4, the program that generates these fails with an OutOfMemoryException. With gcAllowVeryLargeObjects enabled. It went on until 5GB until it crashed. You don't want most of your app to be a Regex, right?
This is not a Regex's job.
This is a two step process because regex is a text parser and not analyzer. But with that said, Regex is perfect for validating that we have the 5:5 number pattern and this regex pattern will determine if we have that form factor \d\d\d\d\d:\d\d\d\d\d right. If that form factor is not found then a match fails and the whole validation fails. If it is valid, we can use regex/linq to parse out the numbers and then check for validity.
This code would be inside a method to do the check
var data = "00515:02151";
var pattern = #"
^ # starting from the beginning of the string...
(?=[\d:]{11}) # Is there is a string that is at least 11 characters long with only numbers and a ;, fail if not
(?=\d{5}:\d{5}) # Does it fall into our pattern? If not fail the match
((?<Values>[^:]+)(?::?)){2}
";
// IgnorePatternWhitespace only allows us to comment the pattern, it does not affect the regex parsing
var result = Regex.Matches(data, pattern, RegexOptions.IgnorePatternWhitespace)
.OfType<Match>()
.Select (mt => mt.Groups["Values"].Captures
.OfType<Capture>()
.Select (cp => int.Parse(cp.Value)))
.FirstOrDefault();
// Two values at this point 515, 2151
bool valid = ((result != null) && (result.First () < result.Last ()));
Console.WriteLine (valid); // True
Using Javascript this can work.
var string = "00515:02152";
string.replace(/(\d{5})\:(\d{5})/, function($1,$2,$3){
return (parseInt($2)<=parseInt($3))?$1:null;
});
FIDDLE http://jsfiddle.net/VdzF7/

c# Regex 0-9 and dash

I have a credit card number that I need to check if it has digits from 0 - 9 and also any dashes.
I have the following:
Match match = Regex.Match(CardNumber, "[0-9-]");
if (match.Success)
{
}
It works but wondering if I missed anything that may not make it work.
Thanks
Right now it only checks if there is at least one digit or dash inside the string CardNumber, so it would return True for the string "hello0!".
If you want to validate the string so it only consists of digits and dashes, you need to use
Match match = Regex.Match(CardNumber, #"^[0-9-]*$");
As a small note to what #Tim wrote, his regex will match -12--34-. Probably what you want is:
^([0-9]+-)*[0-9]+$
This will require at least a digit. If you want the empty string to match, use
^([0-9]+-)*[0-9]*$
(0 or more "groups" of one or more digits plus a - and a final "group" of digits)

Regular expression for accepting alphanumeric characters (6-10 chars) .NET, C#

I am building a user registration form using C# with .NET.
I have a requirement to validate user entered password fields.
Validation requirement is as below.
It should be alphanumeric (a-z , A-Z , 0-9)
It should accept 6-10 characters (minimum 6 characters, maximum 10 characters)
With at least 1 alphabet and number (example: stack1over)
I am using a regular expression as below.
^([a-zA-Z0-9]{6,10})$
It satisfies my first 2 conditions.
It fails when I enter only characters or numbers.
Pass it through multiple regexes if you can. It'll be a lot cleaner than those look-ahead monstrosities :-)
^[a-zA-Z0-9]{6,10}$
[a-zA-Z]
[0-9]
Though some might consider it clever, it's not necessary to do everything with a single regex (or even with any regex, sometimes - just witness the people who want a regex to detect numbers between 75 and 4093).
Would you rather see some nice clean code like:
if not checkRegex(str,"^[0-9]+$")
return false
val = string_to_int(str);
return (val >= 75) and (val <= 4093)
or something like:
return checkRegex(str,"^7[5-9]$|^[89][0-9]$|^[1-9][0-9][0-9]$|^[1-3][0-9][0-9][0-9]$|^40[0-8][0-9]$|^409[0-3]$")
I know which one I'd prefer to maintain :-)
Use positive lookahead
^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{6,10}$
Look arounds are also called zero-width assertions. They are zero-width just like the start and end of line (^, $). The difference is that lookarounds will actually match characters, but then give up the match and only return the result: match or no match. That is why they are called "assertions". They do not consume characters in the string, but only assert whether a match is possible or not.
The syntax for look around:
(?=REGEX) Positive lookahead
(?!REGEX) Negative lookahead
(?<=REGEX) Positive lookbehind
(?<!REGEX) Negative lookbehind
string r = #"^(?=.*[A-Za-z])(?=.*[0-9])[A-Za-z0-9]{6,10}$";
Regex x = new Regex(r);
var z = x.IsMatch(password);
http://www.regular-expressions.info/refadv.html
http://www.regular-expressions.info/lookaround.html

Categories

Resources