MaskInput number format show dash (-) instead of zero - c#

Want to format my number value if number is zero then should show dash ('-') sign instead of zero. what would be the format or MaskInput?
e.g.:
========================================
MyNumberFormatted MyNumberNoFormat
========================================
- 0
5 5
- 0
1 1
========================================

Conditional formatting
string conditionalFormat = "{0:##;-##;-}"; // {0:positive;negative;zero}
Console.WriteLine(string.Format(conditionalFormat, 1));
Console.WriteLine(string.Format(conditionalFormat, -1));
Console.WriteLine(string.Format(conditionalFormat, 0));
https://dotnetfiddle.net/BgFc8j

Related

RegEx to find numbers sequence in string separated by space with predefined maximum length

Sorry for the confusing title, I'll try to explain this with example. Currently we have this expression to find number sequence in a string
\b((\d[ ]{0,1}){13,19})\b
Now I'd like to modify it so it fulfills these rule
- The length should be between 13 to 19 characters, excluding the whitespaces
- Each number cluster must have minimum 3 digits
The expression should mark these as matched:
1234567890123
1234 5678 9012 345
Not match:
123456789012 3
123 12 123 1 23134
Current expression that I have will mark all of them as match.
Example
This is possible using look-around.
The regex can be changed to the following:
\b(?<!\d )(?=(?:\d ?){13,19}(?! ?\d))(?:\d{3,} ?)+\b(?! ?\d)
This works by looking ahead to make sure the number is between 13 and 19 digits long. It then matches groups of 3 or more digits. It then uses negative look ahead after its found all groups of 3 to make sure there aren't any numbers left. If there are, we've found a group smaller than 3. This works on the examples you've provided.
\b Makes sure that its the start of a "word".
(?<!\d ) Make sure there are no numbers behind.
(?=(?:\d ?){13,19}(?! ?\d)) Looks ahead to make sure the number is between 13 and 19 digits long
(?:\d ?){13,19} From original. ?: added to make non-capturing
(?! ?\d) Negative look ahead: if there is still digits left after getting 19 digits, too big therefore discard current match
(?:\d{3,} ?)+ Match any number of clusters bigger than 3 (min 13, max 19 handled by first look ahead)
\b(?! ?\d) Looks for the end of a cluster. If there are still numbers left after the end of the cluster, there must be a cluster that is too small.
Test here
I suggest the following solution also based on lookarounds:
\b\d(?!\d?\b)(?: ?\d(?!(?<= \d)\d?\b)){12,18}\b
See the regex demo
The main point is that we only match the next digit if it is not a part of a 1- or 2-digit group.
Pattern explanation
\b - starting word boundary
\d(?!\d?\b) - a digit that is not followed with 1 or 0 digits and then a trailing word boundary (that is, if it is 12 or 1 like group, it is failed)
(?: ?\d(?!(?<= \d)\d?\b)){12,18} - 12 to 18 occurrences of:
? - 1 or 0 spaces
\d(?!(?<= \d)\d?\b) - any single digit that is not followed with 1 or 0 digits followed with a word boundary (thanks to the (?!\d?\b)), and if that 1 or 0 digits are preceded with space + 1 digit ((?<= \d) lookbehind does that)
\b - a trailing word boundary.
NOTE that in case you want to match these strings in a non-numeric context (that means, if you do not want to allow any digits on the left and on the right) you might also consider adding (?<!\d *) at the front and (?! *\d) at the end of the pattern.
Note that to match any whitespace, you may replace a literal space with \s in the pattern.
If you can use Linq, this will be way easier to maintain:
var myList = new List<string>
{
"1234567890123",
"1234 5678 9012 345",
"123456789012 3",
"123 12 123 1 23134"
};
foreach(var input in myList)
{
var splitted = Regex.Split(input, #"\s+"); // Split on whitespace
var length = splitted.Sum(x => x.Length); // Compute the total length
var smallestGroupSize = splitted.Min(x => x.Length); // Compute the length of the smallest chunck
Console.WriteLine($"Total lenght: {length}, smallest group size: {smallestGroupSize}");
if (length < 13 || length > 19 || smallestGroupSize < 3)
{
Console.WriteLine($"Input '{input}' is incorrect{Environment.NewLine}");
continue;
}
Console.WriteLine($"Input '{input}' is correct!{Environment.NewLine}");
}
which produces:
Total lenght: 13, smallest group size: 13
Input '1234567890123' is correct!
Total lenght: 15, smallest group size: 3
Input '1234 5678 9012 345' is correct!
Total lenght: 13, smallest group size: 1
Input '123456789012 3' is incorrect
Total lenght: 14, smallest group size: 1
Input '123 12 123 1 23134' is incorrect

Regex to get numbers after a period in a string

I'm trying to find the right regex to extract the numbers after the . in the string below. E.g, the first line should return and array of 1 1 1 1 1, the second should return 2 1 0 1 2. I can't seem to figure the correct regex expression to achieve this. Any help would be appreciated.
line = 0.1, 1.1, 2.1, 3.1, 4.1 // payline 0
line = 0.2, 1.1, 2.0, 3.1, 4.2 // payline 1
So far, I have the code below, but it just returns all the the numbers in the sting instead. eg, the first line returns 0 1 1 1 2 1 3 1 4 1 0 and the second returns 0 2 1 1 2 0 3 1 4 2 1
foreach (var line in Paylines)
{
int[] lines = (from Match m in Regex.Matches(line.ToString(), #"\d+")
select int.Parse(m.Value)).ToArray();
foreach (var x in lines)
{
Console.WriteLine(x.ToString());
}
}
You may use a lookbehind-based regex solution:
#"(?<=\.)\d+"
It matches 1+ digits after a dot without placing the dot into a match value.
See the regex demo.
In C#, you may use
var myVals = Regex.Matches(line, #"(?<=\.)\d+", RegexOptions.ECMAScript)
.Cast<Match>()
.Select(m => int.Parse(m.Value))
.ToList();
See the C# demo.
The RegexOptions.ECMAScript option is passed for the \d to only match ASCII digits in the [0-9] range and avoid matching other Unicode digits.

What is String Format C# {0,12:N0} (colon and commas) means?

Okay here's the code example:
string header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
"City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
string output;
foreach (var city in cities) {
output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3)/ (double)city.Item3);
Console.WriteLine(output);
}
}
}
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
i understand about the colon after the args {0:N0} means no decimal, but what about the comas? like {0,-12}, and {1,12} what does comma means after the argument of the string format?
MSDN Documentation is your friend (the link I gave in comments above wasn't the best either):
Composite Formatting
Each format item takes the following form and consists of the following components:
{index[,alignment][:formatString]}
So the index is obviously the index of the provided arguments:
String.Format("Second argument = {1}, first argument = {0}", arg1, arg2);
Alignment specifies the desired width of the field and horizontal alignment:
The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative.
String.Format("{0,-12}" + // first argument, left align, 12 character wide column
"{1,8:yyyy}" + // second argument, right align, 8 character wide column,
// formatted as a year
"{2,12:N0}" + // third argument, right align, 12 character wide column,
// formatted as a number, 0 decimal places
And formatString you already know about (e.g. The Numeric ("N") Format Specifier).
They are index component and alignment component which is part of Composite Formatting. Here is composite formatting syntax;
{index[,alignment][:formatString]}
In your cases, {0,-12} and {1,12}, 0 and 1 are index component which is pointing your first 2 elements that you want to format. And -12 and 12 are alignment components. They can be negative or positive values.
Positive values indicate alignment to the right and negative values indicate alignment to the left.
If you wanna use alignment component, you have to separate it from the index component by a comma. Colon (:) separates alignment component with formatString as you can see on syntax.
Since you use {0,-12} for "Los Angeles" (which is 11 character), it will be aligned with one (12 - 11) white space character to the left.
Console.WriteLine("{0, -12}{1}", "Los Angeles", "1940"); // prints "Los Angeles 1940"
but Chicago (which is 7 character), it will be aligned five (12 - 7) white space character to the left as;
Console.WriteLine("{0, -12}{1}", "Chicago", "1940"); // prints "Chicago 1940"
For positive values;
Console.WriteLine("{0, 12}{1}", "Los Angeles", "1940"); // prints " Los Angeles1940"
but
Console.WriteLine("{0, 12}{1}", "Chicago", "1940"); // prints " Chicago1940"
The Numeric ("N") Format Specifier
The numeric ("N") format specifier converts a number to a string of
the form "-d,ddd,ddd.ddd…", where "-" indicates a negative number
symbol if required, "d" indicates a digit (0-9), "," indicates a group
separator, and "." indicates a decimal point symbol. The precision
specifier indicates the desired number of digits after the decimal
point. If the precision specifier is omitted, the number of decimal
places is defined by the current NumberFormatInfo.NumberDecimalDigits
property.
The result string is affected by the formatting information
of the current NumberFormatInfo object. The following table lists the
NumberFormatInfo properties that control the formatting of the result
string.
For N0 the actual output will no contains digits after the decimal point (like in integer values).
Align numbers with spaces
To align float number to the right use comma „,“ option before the
colon. Type comma followed by a number of spaces, e.g. „0,10:0.0“
(this can be used only in String.Format method, not in double.ToString
method). To align numbers to the left use negative number of spaces.

How to validate using Regex

My Requirement is that
My first two digits in entered number is of the range 00-32..
How can i check this through regex in C#?
I could not Figure it out !!`
Do you really need a regex?
int val;
if (Int32.TryParse("00ABFSSDF".Substring(0, 2), out val))
{
if (val >= 0 && val <= 32)
{
// valid
}
}
Since this is almost certainly a learning exercise, here are some hints:
Your rexex will be an "OR" | of two parts, both validating the first two characters
The first expression part will match if the first character is a digit is 0..2, and the second character is a digit 0..9
The second expression part will match if the first character is digit 3, and the second character is a digit 0..2
To match a range of digits, use [A-B] range, where A is the lower and B is the upper bound for the digits to match (both bounds are inclusive).
Try something like
Regex reg = new Regex(#"^([0-2]?[0-9]|3[0-2])$");
Console.WriteLine(reg.IsMatch("00"));
Console.WriteLine(reg.IsMatch("22"));
Console.WriteLine(reg.IsMatch("33"));
Console.WriteLine(reg.IsMatch("42"));
The [0-2]?[0-9] matches all numbers from zero to 29 and the 3[0-2] matches 30-32.
This will validate number from 0 to 32, and also allows for numbers with leading zero, eg, 08.
You should divide the region as in:
^[012]\d|3[012]
if(Regex.IsMatch("123456789","^([0-2][0-9]|3[0-2])"))
// match

regular expression for 2 string arguments having numeric values with range constraint

I need to validate console input arguments. User can pass only 2 arguments separated by Space.
First argument should be between 1 to 100
Second argument should be between 1 to 750.
I need a regular expression to validate the input. Please help.
Description
this regex will match 1-100 space 1-750
^\b([1-9][0-9]?|100)\b\s+\b([1-9][0-9]?|[1-6][0-9]{2}|7[0-4][0-9]|750)\b$
Expanded
^ match the start of the string
\b match the word boundary
( open capture group 1
[1-9] match any single digit not including zero followed by
[0-9]? match any single digit or no digit
| or
100 match the number one hundred
) close the capture group 1
\b\s+\b require a word break, space, and word break.
( start capture group 2
[1-9] match any single digit not including zero followed by
[0-9]? match any single digit or no digit
| or
[1-6] match any digits 1 thru 6 followed by
[0-9]{2} match two of any digits
| or
7 match a seven followed by
[0-4] match digits 0 thru 4 followed by
[0-9] match any single digit
| or
750 match the number seven hundred and fifty
) close the capture group
\b$ require a word break and end of string.
It sounds like you want a pattern like this:
^(1|[1-9]\d|100)\s+(1|[1-9]\d|[1-6]\d\d|7[0-5]\d)$
However, you are probably better off verifying the inputs via normal integer comparison:
int int1, int2;
if (int.TryParse(param1, out int1) && int.TryParse(param2, out int2))
{
if (int1 >= 1 && int1 <= 100 && int2 >= 1 && int2 <= 750)
{
...
}
}
As others have said, regex isn't the best option, but if you really want to use it, this seems to work...
^(?:100|[1-9]\d?) (?:[1-7](?:[0-4]\d|50)|[1-9]\d?)$
I rather recommend not using regex but something like this:
int a=0,b=0;
if(args.Length != 2){
// not 2 arguments
}else{
if(!int.TryParse(args[0], out a) || !int.TryParse(args[1], out b)){
// not numbers
}else{
if(a < 1 || a > 100 || b < 1 || b > 750){
// out of ranges
}else{
// everything fine
}
}
}
and you'll have your numbers right there.

Categories

Resources