Regular expression for checking a number range (with decimals) - c#

I am working on a window form which accepts certain range of value as input. So far, I could only find the range between 0 and 20000.
(20000|[0-9]|0[1-9]|[1-9]\d{0,3})$
Can somebody kindly help me with finding the range between 0.0 and 20479.0 (including decimals)?

As comments suggest, regex is far from ideal in these cases. It can be done though, but get quite complex.
^(?:(?:1?\d{1,4}|20[0-3]\d\d|204[0-6]\d|2047[0-8])(?:\.\d+)?|20479(?:\.0+)?)$
This does it using two outer alternations - one to match the maximum number and optionally any number of zeroes as decimals. The other (first) has several sub-alternations matching the maximum for the different digits, and allowing an optional decimal point and decimals.
1?\d{1,4} Matches 0-19999
20[0-3]\d\d Matches 20000-20399
204[0-6]\d Matches 20400-20469
2047[0-8] Matches 20470-20478
See it here at regex101.

Here is a suggestion that allows numbers between 0 and 20479 with decimals:
^(0?[0-9]{0,4}(?:\.\d+)?|1\d{4}(?:\.\d+)?|20[0-4][0-7][0-8](?:\.\d+)?|20479(?:\.[0-7])?)$
As you can see, it is a bit complex, you may not want to do it with a regex.
Demo on regex101
Explanation
(0?[0-9]{0,4}(?:\.\d+)? between 0.0 and 9999.99 (decimals are optional)
1\d{4}(?:\.\d+)? between 10000.0 and 19999.99 (decimals are optional)
20[0-4][0-7][0-8](?:\.\d+)? between 20000.0 and 2048.99 (decimals are optional)
20479(?:\.[0-7])? between 20479 and 20479.7
Update: Without decimals, you can use:
^(0?[0-9]{0,4}|1\d{4}|20[0-4][0-7][0-8]|20479$

If you expect only integers (.0 at the end) you could try this
Mask is
^((1?[0-9]{0,4})|((20(([0-3][0-9]{0,2})|(4[0-7][0-9])))))$
If you need .0 at the end add \.0 before $. If you need double/decimal than precision/range would be required.

Why would you use a regex that'll be hardly maintainable when you can use real code:
public bool IsValid(string input = "")
{
double inputParsed;
if (!double.TryParse(input, out inputParsed))
return false;
if(inputParsed < 0 || inputParsed > 20479)
return false;
return true;
}

Using regex get two numbers before and after the point.
Then check the numbers to hit the range.
var list = new List<string> { "VB0.0", "VB20479.0", "VB20479.7", "VB20480.0", "VB010000.0", "VB0.8", "VBx.y" };
string pattern = #"(\d+)\.(\d+)";
foreach (var input in list)
{
var m = Regex.Match(input, pattern);
if (m.Success)
{
string value1 = m.Groups[1].Value;
string value2 = m.Groups[2].Value;
bool result = value1.Length <= 5 && int.Parse(value1) <= 20479
&& value2.Length <= 1 && int.Parse(value2) <= 7;
Console.WriteLine(result);
}
else Console.WriteLine(false);
}

Related

Regular expression for 0 or a positive number

I need a regular expression to check that a string's value is either a '0', or a positive number with a length equal to 1 to 10 (also where the first digit cannot be zero).
I'm stuck, I can get the 0, but I can't get the positive number.
Here is what I have:
(^([0])$)|(^([1-9][0-9]{0-9})$)
This reg exp looks a little crazy, I've been trying a lot of different things and making even more crazier and crazier.
For a range of possibilities, you use a comma, not a hyphen.
(^([0])$)|(^([1-9][0-9]{0,9})$)
However, your regex can be shortened to:
^(0|[1-9][0-9]{0,9})$
offering the faster, non-Regex approach:
static void Main(string[] args
{
string str = "12";
long test;
if(str.Length <= 10
&& long.TryParse(str, out test)
&& test >= 0)
{
//valid
}
}

Regex. Up to six digits after separator but not all zeros

I need input in this form:
first digit ist always 0
second is always . or ,
than up to six digits, but only digits not letters or other symbols
and not all zeros
private const string Pattern = #"^0(,|.)(?!0+$)+";
var regex = new Regex(Pattern, RegexOptions.IgnoreCase);
if (!regex.IsMatch(inputToCheck))
{...}
This works ok for all the conditions except one with digits only.
This input should be disabled too: "0,01a", "0.01a1", "0,01a0"
How can I extend my regex pattern to this condition?
Some examples of valid and invalid input.
Valid:
0,123456
0,01
0,010
0,2
invalid:
1,123456
2,123456
0,0
0,00
0,000
a
a,1
0,01a
0,01a1
0,01a0
I think you're on the right track. Here's my solution to this:
^0[,.](?!0+$)\d{1,6}$
This will make sure that the first digit is zero. It then checks that the next character is either a comma or a dot. Then, using a lookahead it ensures that the rest of the subject string is not entirely zeros. If this passes, it checks that the remaining characters are all digits.
You can use a regex like this:
^0[.,][1-9]{0,6}$
Of course this regex don't allow 0 after the , or .. If you want to allow 0 but restrict ending by 0 you can do:
^0[.,][0-9]{0,5}[1-9]$
And also you can shorten it a little to:
^0[.,]\d{0,5}[1-9]$
Try this expression
^^0(,|.)([0-9]{1,4}$)+
You shouldn't really be using regex to parse numbers, you can do it by just validating it as a number as so..
CultureInfo culture = new CultureInfo("de-DE");
string[] inputs = new string[]{"0,123456",
"0,01",
"1,123456",
"0,0"};
foreach(var input in inputs)
{
double val;
if(Double.TryParse(input, NumberStyles.Number, culture, out val)
&& Math.Round(val, 6) == val
&& val != 0.0
&& (int)val == 0)
Console.WriteLine("{0} is valid", input);
else
Console.WriteLine("{0} is invalid", input);
}
Output
0,123456 is valid
0,01 is valid
1,123456 is invalid
0,0 is invalid
IDEOne example

Simple regex failing test to determine a 3 digit number

I have had a difficult time wrapping my head around regular expressions. In the following code, I used a Regex to determine if the data passed was a 1 to 3 digit number. The expression worked if the data started with a number (ex. "200"), but also passed if the data had a letter not in the first digit (ex. "3A5"). I managed to handle the error with the INT32.TryParse() method, but it seems there should be an easier way.
if (LSK == MainWindow.LSK6R)
{
int ci;
int length = SP_Command.Length;
if (length > 3) return MainWindow.ENTRY_OUT_OF_RANGE; //Cannot be greater than 999
String pattern = #"[0-9]{1,3}"; //RegEx pattern for 1 to 3 digit number
if (Regex.IsMatch(SP_Command, pattern)) //Does not check for ^A-Z. See below.
{
bool test = Int32.TryParse(SP_Command, out ci); //Trying to parse A-Z. Only if
if (test) //it no letter will it succeed
{
FlightPlan.CostIndex = ci; //Update the flightplan CI
CI.Text = ci.ToString(); //Update the Init page
}
else return MainWindow.FORMAT_ERROR; //It contained a letter
}
else return MainWindow.FORMAT_ERROR; //It didn't fit the RegEx
}
Regex.IsMatch searches the input string for the pattern (and thus returns true for 3A5 because it finds 3).
You should also include start (^) and end ($) of string:
String pattern = #"^[0-9]{1,3}$";
Adding line begin/end should help.
^[0-9]{1,3}$

.Net Removing all the first 0 of a string

I got the following :
01.05.03
I need to convert that to 1.5.3
The problem is I cannot only trim the 0 because if I got :
01.05.10
I need to convert that to 1.5.10
So, what's the better way to solve that problem ? Regex ? If so, any regex example doing that ?
Expanding on the answer of #FrustratedWithFormsDesigner:
string Strip0s(string s)
{
return string.Join<int>(".", from x in s.Split('.') select int.Parse(x));
}
Regex-replace
(?<=^|\.)0+
with the empty string. The regex is:
(?<= # begin positive look-behind (i.e. "a position preceded by")
^|\. # the start of the string or a literal dot †
) # end positive look-behind
0+ # one or more "0" characters
† note that not all regex flavors support variable-length look-behind, but .NET does.
If you expect this kind of input: "00.03.03" and want to to keep the leading zero in this case (like "0.3.3"), use this expression instead:
(?<=^|\.)0+(?=\d)
and again replace with the empty string.
From the comments (thanks Kobi): There is a more concise expression that does not require look-behind and is equivalent to my second suggestion:
\b0+(?=\d)
which is
\b # a word boundary (a position between a word char and a non-word char)
0+ # one or more "0" characters
(?=\d) # positive look-ahead: a position that's followed by a digit
This works because the 0 happens to be a word character, so word boundaries can be used to find the first 0 in a row. It is a more compatible expression, because many regex flavors do not support variable-length look-behind, and some (like JavaScript) no look-behind at all.
You could split the string on ., then trim the leading 0s on the results of the split, then merge them back together.
I don't know of a way to do this in a single operation, but you could write a function that hides this and makes it look like a single operation. ;)
UPDATE:
I didn't even think of the other guy's regex. Yeah, that will probably do it in a single operation.
Here's another way you could do what FrustratedWithFormsDesigner suggests:
string s = "01.05.10";
string s2 = string.Join(
".",
s.Split('.')
.Select(str => str.TrimStart('0'))
.ToArray()
);
This is almost the same as dtb's answer, but doesn't require that the substrings be valid integers (it would also work with, e.g., "000A.007.0HHIMARK").
UPDATE: If you'd want any strings consisting of all 0s in the input string to be output as a single 0, you could use this:
string s2 = string.Join(
".",
s.Split('.')
.Select(str => TrimLeadingZeros(str))
.ToArray()
);
public static string TrimLeadingZeros(string text) {
int number;
if (int.TryParse(text, out number))
return number.ToString();
else
return text.TrimStart('0');
}
Example input/output:
00.00.000A.007.0HHIMARK // input
0.0.A.7.HHIMARK // output
There's also the old-school way which probably has better performance characteristics than most other solutions mentioned. Something like:
static public string NormalizeVersionString(string versionString)
{
if(versionString == null)
throw new NullArgumentException("versionString");
bool insideNumber = false;
StringBuilder sb = new StringBuilder(versionString.Length);
foreach(char c in versionString)
{
if(c == '.')
{
sb.Append('.');
insideNumber = false;
}
else if(c >= '1' && c <= '9')
{
sb.Append(c);
insideNumber = true;
}
else if(c == '0')
{
if(insideNumber)
sb.Append('0');
}
}
return sb.ToString();
}
string s = "01.05.10";
string newS = s.Replace(".0", ".");
newS = newS.StartsWith("0") ? newS.Substring(1, newS.Length - 1) : newS;
Console.WriteLine(newS);
NOTE: You will have to thoroughly check for possible input combination.
This looks like it is a date format, if so I would use Date processing code
DateTime time = DateTime.Parse("01.02.03");
String newFormat = time.ToString("d.M.yy");
or even better
String newFormat = time.ToShortDateString();
which will respect you and your clients culture setting.
If this data is not a date then don't use this :)
I had a similar requirement to parse a string with street adresses, where some of the house numbers had leading zeroes and I needed to remove them while keeping the rest of the text intact, so I slightly edited the accepted answer to meet my requirements, maybe someone finds it useful. Basically doing the same as accepted answer, with the difference that I am checking if the string part can be parsed as an integer, and defaulting to the string value when false;
string Strip0s(string s)
{
int outputValue;
return
string.Join(" ",
from x in s.Split(new[] { ' ' })
select int.TryParse(x, out outputValue) ? outputValue.ToString() : x);
}
Input: "Islands Brygge 34 B 07 TV"
Output: "Islands Brygge 34 B 7 TV"

How to get number from a string

I would like to get number from a string eg:
My123number gives 123
Similarly varchar(32) gives 32 etc
Thanks in Advance.
If there is going to be only one number buried in the string, and it is going to be an integer, then something like this:
int n;
string s = "My123Number";
if (int.TryParse (new string (s.Where (a => Char.IsDigit (a)).ToArray ()), out n)) {
Console.WriteLine ("The number is {0}", n);
}
To explain: s.Where (a => Char.IsDigit (a)).ToArray () extracts only the digits from the original string into an array of char. Then, new string converts that to a string and finally int.TryParse converts that to an integer.
you could go the regular expression way. which is normally faster than looping through the string
public int GetNumber(string text)
{
var exp = new Regex("(\d+)"); // find a sequence of digits could be \d+
var matches = exp.Matches(text);
if (matches.Count == 1) // if there's one number return that
{
int number = int.Parse(matches[0].Value);
return number
}
else if (matches.Count > 1)
throw new InvalidOperationException("only one number allowed");
else
return 0;
}
Loop through each char in the string and test it for being a number. remove all non-numbers and then you have a simple integer as a string. Then you can just use int.parse.
string numString;
foreach(char c in inputString)
if (Char.IsDigit(c)) numString += c;
int realNum = int.Parse(numString);
You could do something like this, then it will work with more then one number as well
public IEnumerable<string> GetNumbers(string indata)
{
MatchCollection matches = Regex.Matches(indata, #"\d+");
foreach (Match match in matches)
{
yield return match.Value;
}
}
First write a specification of what you mean by a "number" (integer? long? decimal? double?) and by "get a number from a string". Including all the cases you want to be able to handle (leading/trailing signs? culture-invariant thousands/decimal separators, culture-sensitive thousands/decimal separators, very large values, strings that don't contain a valid number, ...).
Then write some unit tests for each case you need to be able to handle.
Then code the method (should be easy - basically extract the numeric bit from the string, and try to parse it. Some of the answers provided so far will work for integers provided the string doesn't contain a value larger than Int32.MaxValue).

Categories