Getting the number of Format specifiers in a string? - c#

When using string.Format(string, object[]) it throws an exception if string contains more format specifiers ({0}, {1:dd-MM-yyyy} etc.) than object[].Length.
I'd like to also throw an exception if object[].Length contains more specifiers. There seems to be no built-in way to do it, so I'm trying to get the number of format specifiers in the input string. The tricky bit is that stuff like {{something}} or {0:dd-MM-yyyy} is allowed.
Does anyone know an easy or even built-in way to get the number of format specifiers in a string? I'm currently trying to build a regex, but maybe there is an easier way?

Looks like someone has already built a regex for this: Is there a better way to count string format placeholders in a string in C#?

Related

c#: DateTime.Parse() -- Unrecognized datetime-string

So I got this datetime-string which I get from an external API, "2014-08-28T11:00:00:000-0400".
But I am unable to parse it into a normal DateTime object in C#, I know that last part of the string has something to do with timezone offsets or something, but I am at a loss as to what to do in order for it to parse.
What I've tried so far:
DateTime.Parse("2019-11-13T05:20:14:311-0700")
DateTime.Parse("2019-11-13T05:20:14:311-0700", new System.Globalization.CultureInfo("en-GB"))
DateTime.Parse("2019-11-13T05:20:14:311-0700", new System.Globalization.CultureInfo("en-US"))
DateTimeOffset.Parse("2019-11-13T05:20:14:311-0700")
A whole other bunch of stuff where I've passed in various format strings like "yyyy-MM-dd:HH:mm:ss" but that doesn't do any good either
Please, if someone out there can help me, you'll get a virtual cookie!
The format string you want to use is either
yyyy-MM-dd'T'HH:mm:ss:fffzzz
or
yyyy-MM-dd'T'HH:mm:ss:fffK
More information for zzz can be found here or for K here
You can use the above format string with either DateTime.ParseExact or DateTimeOffset.ParseExact depending on what you're trying to achieve.
Live example: https://rextester.com/DTNT63275

How to use string format to omit period but leave digits

I have the format string ######.00 used for formatting decimals in C#. I need to change it so that it omits the period but keeps the digits following the period. Can I accomplish this just by changing the format? I've searched, but haven't been able to find a solution online.
I found this answer to a very similar question, but it involves multiplying the decimal by 100 before formatting it. I'm not able to manipulate the number going in, nor the resulting string because I don't have access to them. This is because we're using a function from a third-party library that fetches the number from elsewhere and displays it formatted to the UI. I can only provide it with a format string. (If manipulating the number or resulting string is the only way to get it in the format we can probably do it, it would just take a good deal of refactoring, so I wanted to see if there's a simpler solution first. Hence the constraints.)
Just as an example of the output I'm looking for, consider the following code:
var myFormat = "{0:######.00}";
Console.WriteLine(string.Format(myFormat, 1234.1234));
Console.WriteLine(string.Format(myFormat, 5));
The code above currently outputs 1234.12 and 5.00, but I would like it to output 123412 and 500 just by changing myFormat. Is there a way to do this?
If only the format string is what you can change, there's probably no way to remove the dot.
However, you can implement your own Formatter, as MSDN's example.
string.Format(new CustomerFormatter(), "{0}", 1234.1234)

custom string format puzzler

We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.

VB6 Format equivalent in C#

I am converting some VB6 code to C# and am having a problem duplicating certain functionality. I have a string representation of a number ex.6000 and a format specifier of ex. ###0.000.
VB6 Example:
Format(number, "########0.000") = "6.000"
I am having trouble finding the C# equivalent to duplicate this functionality. The methods I have tried with ToString() but they are more for formatting the actual number rather than more of an overlay format like VB6 is doing.
C# Example:
number.ToString("########0.000", CultureInfo.InvariantCulture) = 6000.000
Personally, I think you should simply revisit your inputs and numeric specifiers to be more appropriate, but: you could cheat with:
string s = number.ToString(#"########0\.000", CultureInfo.InvariantCulture)
The \. is now not the decimal point specifier, but a literal. Horrible horrible answer. Please don't do it.
you can use the "FormatNumber" function instead

C# convert any format string to double

I tried searching google and stackoverflow without success.
I'm having a problem with "Input string was not in a correct format." exception with an application I'm working at.
Thing is, that I convert some double values to strings with doubleNumber.ToString("N2"); in order to store them in XML file. When I switch testing machines, XML file stored on one can't be returned back to double values.
I've tried all of the solutions I could think of, but setting number culture didn't work, using CultureInfo.InvariantCulture, replacing characters also doesn't work. Sometimes the values are stored like "3,001,435.57" and sometimes (on other PC) like "3.001.435,57".
Is there some function or a way to parse a double from string, whatever the input format is?
Thanks.
You have to specify a culture because (eg.) "3,001" is ambiguous - is it 3.001 or 3001?
Depending on what your numbers look like, perhaps you could attempt to detect the culture by counting number of , and . characters and/or checking their positions.
Here is what you are looking for...
http://msdn.microsoft.com/en-us/library/9s9ak971.aspx
This will accept a string variable and a format provider. You need to create a format provider that provides the culture information you are looking to convert out of.

Categories