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
Related
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);
}
Hi i need a Regex Expression for extracting only floating point numbers from right to left
Example string
Earning per Equity Share (in ) face value of 2 each26 1,675.10
1,252.56
My current Regex
(\+|-)?[0-9][0-9]*(\,[0-9]*)?(\.[0-9]*)? with Rex options-Right to left
but
Current Output is
1,252.56
1,675.10
26
2
However i do not want to match on 26 or 2
Please help me
Maybe something like this will help
Regex
/[-+]?[0-9,\.]*([,\.])[0-9]*/g
Example input
Earning -34 5 b4 pe8r blah4 t3st + - (in) 1,252.56 face
-12234,23423.342 of 1,675.10 1,252.56
Matches
1,252.56
-12234,23423.342
1,675.10
1,252.56
Explanation
[-+]? match a single character present in the list below
Quantifier: ? Between zero and one time, as many times as possible, giving back as needed [greedy]
-+ a single character in the list -+ literally
[0-9,\.]* match a single character present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
, the literal character ,
\. matches the character . literally
1st Capturing group ([,\.])
[,\.] match a single character present in the list below
, the literal character ,
\. matches the character . literally
[0-9]* match a single character present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
g modifier: global. All matches (don't return on first match)
Although this is a Regex question this is also taged as C#.
Below is an example of how you might get a little bit more control over your output.
It's also culture-specific and only picks up numbers with a decimal place, and has no false positives.
Method
private List<double> GetNumbers(string input)
{
// declare result
var resultList = new List<double>();
// if input is empty return empty results
if (string.IsNullOrEmpty(input))
{
return resultList;
}
// Split input in to words, exclude empty entries
var words = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// set your desirted culture
var culture = CultureInfo.CreateSpecificCulture("en-GB");
// Refine words into a list that represents potential numbers
// must have decimal place, must not start or end with decimal place
var refinedList = words.Where(x => x.Contains(".") && !x.StartsWith(".") && !x.EndsWith("."));
foreach (var word in refinedList)
{
double value;
// parse words using designated culture, and the Number option of double.TryParse
if (double.TryParse(word, NumberStyles.Number, culture, out value))
{
resultList.Add(value);
}
}
return resultList;
}
Usage
var testString = "Earning -34 5 b4 , . 234. 234, ,345 45.345 $234234 234.3453.345 $23423.2342 +234 -23423 pe8r blah4 t3st + - (in) 1,252.56 face -12234,23423.342 of 1,675.10 1,252.56";
var results = GetNumbers(testString);
foreach (var item in results)
{
Debug.WriteLine("{0}", item);
}
Output
45.345
1252.56
-1223423423.342
1675.1
1252.56
Additional Notes
You can learn more about double.TryParse and its options here.
You can learn more about the CultureInfo Class here.
I want to validate a string based on a custom format: ___.___ or ___,___, 3 numbers followed by a dot or comma followed by 3 numbers (e.g. 123.456 or 123,456).
Currently, I have following code:
string InputText = "123.456"
bool result, result1, result2;
int test, test2;
result = Int32.TryParse(InputText.Substring(0, 3), out test);
result1 = (InputText[3] == '.' || InputText[3] == ',') ? true : false;
result2 = Int32.TryParse(InputText.Substring(4, 3), out test2);
if (result == false || result1 == false || result2 == false)
{
Console.WriteLine("Error! Wrong format.");
}
This works just fine, however, this seems rather inefficient and unnecessarily complex; is there an alternative to this?
Is there an alternative to this? Yes you can use Regex.IsMatch to do this.
String s = "123.456";
if (!Regex.IsMatch(s, #"^\d{3}[.,]\d{3}$")) {
Console.WriteLine("Error! Wrong format.");
}
Explanation:
^ # the beginning of the string
\d{3} # digits (0-9) (3 times)
[.,] # any character of: '.', ','
\d{3} # digits (0-9) (3 times)
$ # before an optional \n, and the end of the string
Pattern to validate 3 numbers followed by a dot or comma followed by 3 numbers is,
^\d{3}[,.]\d{3}$
DEMO
Aditional to Avinash answer if you want to capture the numbers matching the format you can use the following regex:
\b(\d{3}[.,]\d{3})\b
Working demo
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}$
string sentence = "X10 cats, Y20 dogs, 40 fish and 1 programmer.";
string[] digits = Regex.Split (sentence, #"\D+");
For this code I get these values in the digits array
10,20,40,1
string sentence = "X10.4 cats, Y20.5 dogs, 40 fish and 1 programmer.";
string[] digits = Regex.Split (sentence, #"\D+");
For this code I get these values in the digits array
10,4,20,5,40,1
But I would like to get like
10.4,20.5,40,1
as decimal numbers. How can I achieve this?
Small improvement to #Michael's solution:
// NOTES: about the LINQ:
// .Where() == filters the IEnumerable (which the array is)
// (c=>...) is the lambda for dealing with each element of the array
// where c is an array element.
// .Trim() == trims all blank spaces at the start and end of the string
var doubleArray = Regex.Split(sentence, #"[^0-9\.]+")
.Where(c => c != "." && c.Trim() != "");
Returns:
10.4
20.5
40
1
The original solution was returning
[empty line here]
10.4
20.5
40
1
.
The decimal/float number extraction regex can be different depending on whether and what thousand separators are used, what symbol denotes a decimal separator, whether one wants to also match an exponent, whether or not to match a positive or negative sign, whether or not to match numbers that may have leading 0 omitted, whether or not extract a number that ends with a decimal separator.
A generic regex to match the most common decimal number types is provided in Matching Floating Point Numbers with a Regular Expression:
[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?
I only changed the capturing group to a non-capturing one (added ?: after (). It matches
If you need to make it even more generic, if the decimal separator can be either a dot or a comma, replace \. with a character class (or a bracket expression) [.,]:
[-+]?[0-9]*[.,]?[0-9]+(?:[eE][-+]?[0-9]+)?
^^^^
Note the expressions above match both integer and floats. To match only float/decimal numbers make sure the fractional pattern part is obligatory by removing the second ? after \. (demo):
[-+]?[0-9]*\.[0-9]+(?:[eE][-+]?[0-9]+)?
^
Now, 34 is not matched: is matched.
If you do not want to match float numbers without leading zeros (like .5) make the first digit matching pattern obligatory (by adding + quantifier, to match 1 or more occurrences of digits):
[-+]?[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?
^
See this demo. Now, it matches much fewer samples:
Now, what if you do not want to match <digits>.<digits> inside <digits>.<digits>.<digits>.<digits>? How to match them as whole words? Use lookarounds:
[-+]?(?<!\d\.)\b[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.\d)
And a demo here:
Now, what about those floats that have thousand separators, like 12 123 456.23 or 34,345,767.678? You may add (?:[,\s][0-9]+)* after the first [0-9]+ to match zero or more sequences of a comma or whitespace followed with 1+ digits:
[-+]?(?<![0-9]\.)\b[0-9]+(?:[,\s][0-9]+)*\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.[0-9])
See the regex demo:
Swap a comma with \. if you need to use a comma as a decimal separator and a period as as thousand separator.
Now, how to use these patterns in C#?
var results = Regex.Matches(input, #"<PATTERN_HERE>")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
try
Regex.Split (sentence, #"[^0-9\.]+")
You'll need to allow for decimal places in your regular expression. Try the following:
\d+(\.\d+)?
This will match the numbers rather than everything other than the numbers, but it should be simple to iterate through the matches to build your array.
Something to keep in mind is whether you should also be looking for negative signs, commas, etc.
Check the syntax lexers for most programming languages for a regex for decimals.
Match that regex to the string, finding all matches.
If you have Linq:
stringArray.Select(s=>decimal.Parse(s));
A foreach would also work. You may need to check that each string is actually a number (.Parse does not throw en exception).
Credit for following goes to #code4life. All I added is a for loop for parsing the integers/decimals before returning.
public string[] ExtractNumbersFromString(string input)
{
input = input.Replace(",", string.Empty);
var numbers = Regex.Split(input, #"[^0-9\.]+").Where(c => !String.IsNullOrEmpty(c) && c != ".").ToArray();
for (int i = 0; i < numbers.Length; i++)
numbers[i] = decimal.Parse(numbers[i]).ToString();
return numbers;
}