custom string format 0,0 with slash or back slash - c#

i have a WPF TextBox that user can type number in that . now i am searching for a string format that can separate TextBox number each 3 point (like 0,0) but i want separate text with Slash or Back Slash or another character. and we do not know how many point our number has.
i am searching for string format not Linq solution or etc . i read Microsoft help but cant find any way .
sample = 123456789 == > 123/456/789 (good) --- 123,456,789 (bad)
Update :
Thanks guys but i search for some thing like this stringformat= {}{0:0,0} etc . i mean dont want use string function like regex , replace or linq or any c# code . i want use a string like {#,#} or etc. see microsoft link in my post i need create a string for my issue.

As the OP insists on the use of String.Format:
string input; //the input of your textbox
int temp = int.Parse(input); //parse your input into an int
//the Format() adds the decimal points, the replace replaces them with the /
string output = String.Format("{0:0,0}", temp).Replace('.', '/');
The important step here is to cast the text of your textbox into an integer, as this simplifies the insertion of the decimal points with String.Format().
Of course, you have to make sure that your textbox is a valid number upon parsing or you may get an exception.
EDIT
So... you have some dynamic-length number and want to format it using a static format-string (as regexes, string replaces, ling or any c# code at all (!) are a no go)? This is impossible.
You HAVE TO have some dynamic code creating a format string somewhere.
Without referencing to regexes or string replaces again, here is some code to create a format string depending on your input number.
This way you have just one String.Format() call. Perhaps you can put the algorithm to create the format string somewhere else and just call it from whereever you need it.
string input; //the input of your textbox
int temp = int.Parse(input); //parse your input into an int
string customString = "{0:";
string tempS = "";
for (int i = 0; i < input.Length; i++)
{
if (i % 3 == 0 && i != 0)
{
tempS += "/";
}
tempS += "#";
}
tempS = new string(tempS.Reverse().ToArray());
customString += tempS;
customString += "}";
string output = String.Format(customString, temp));

You can use a custom NumberFormatInfo. Then use it for ToString with the "n"-format specifier:
NumberFormatInfo nfi = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
nfi.NumberGroupSeparator = "/";
nfi.NumberDecimalDigits = 0; // otherwise the "n" format specifier adds .00
Console.Write(123456789.ToString("n", nfi)); // 123/456/789

You can use NumberFormatInfo.NumberGroupSeparator Property
Sample from MSDN
using System;
using System.Globalization;
class NumberFormatInfoSample {
public static void Main() {
// Gets a NumberFormatInfo associated with the en-US culture.
NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;
// Displays a value with the default separator (",").
Int64 myInt = 123456789;
Console.WriteLine( myInt.ToString( "N", nfi ) );
// Displays the same value with a blank as the separator.
nfi.NumberGroupSeparator = " ";
Console.WriteLine( myInt.ToString( "N", nfi ) );
}
}
/*
This code produces the following output.
123,456,789.00
123 456 789.00
*/
for you - set NumberGroupSeparator property to '/'
UPDATE
another sample
var t = long.Parse("123/456/789",NumberStyles.Any, new NumberFormatInfo() { NumberGroupSeparator = "/" });
var output = string.Format(new NumberFormatInfo() { NumberGroupSeparator="/"}, "{0:0,0}", t);

Related

c# How to separate an int with decimal points?

I am trying to format an int with decimal points as separators, not commas.
Example: 1234567890 should be formatted to 1.234.567.890
text_team1.text = em.team1Score.ToString("#,##0");
This will give 1,234,567,890
However in this topic there was some information about using the class CultureInfo which contains the format-style, so I used several of them:
text_team1.text = em.team1Score.ToString("#,##0", new System.Globalization.CultureInfo("IS-is"));
as an example. But it seems that every cultureInfo uses a comma as separator.
Even by editing the string afterwards, there is still the comma as seperator.
text_team1.text = em.team1Score.ToString("#,##0");
text_team1.text.Replace(',','.');
Even by editing the string afterwards, there is still the comma as
seperator.
text_team1.text = em.team1Score.ToString("#,##0");
text_team1.text.Replace(',','.');
You forgot to assign the replaced string back.
text_team1.text = text_team1.text.Replace(',','.');
EDIT:
If you still prefer a solution without using the Replace function, you can use the Extension method below. It works for strings and ints. Please Google and read about extension methods if you don't know how they work.
Create and place the ExtensionMethod script in any folder in your project:
using System.Globalization;
using System;
public static class ExtensionMethod
{
public static string formatStringWithDot(this string stringToFormat)
{
string convertResult = "";
int tempInt;
if (Int32.TryParse(stringToFormat, out tempInt))
{
convertResult = tempInt.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
}
return convertResult;
}
public static string formatStringWithDot(this int intToFormat)
{
string convertResult = "";
convertResult = intToFormat.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
return convertResult;
}
}
Usage:
string stringToFormat = "1234567890";
Debug.Log(stringToFormat.formatStringWithDot());
Or
int intToFormat = 1234567890;
Debug.Log(intToFormat.formatStringWithDot());
Or
string stringToFormat = "1234567890";
text_team1.text = stringToFormat.formatStringWithDot();
Use each one depending on which scenario you run into.
If you are using globalisation as a means to format your string, you could set a Custom Group Seperator
NumberFormatInfo nfi = new CultureInfo( "en-US", false ).NumberFormat;
// Displays the same value with a blank as the separator.
Int64 myInt = 1234567890;
nfi.NumberGroupSeparator = ".";
Console.WriteLine( myInt.ToString( "N0", nfi ) );
https://dotnetfiddle.net/vRqd6x
I prefer using string.Format().
Does your OS represent numbers with that format? If so, you can try with the simplest form
text_team1.text = string.Format("{0:N}", em.team1Score);
or you can force it with
text_team1.text = string.Format(CultureInfo.GetCultureInfo("IS-is"), "{0:N}", em.team1Score);
which cares of the culture.

Make TryParse compatible with comma or dot decimal separator

The problem:
Let's assume you are using a dot "." as a decimal separator in your regional setting and have coded a string with a comma.
string str = "2,5";
What happens when you decimal.TryParse(str, out somevariable); it?
somevariable will assume 0.
What can you do to solve it?
1-
You can
decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out somevariable);
And it will return 25, and not 2.5 which is wrong.
2-
You can
decimal.TryParse(str.Replace(",","."), out num);
And it will return the proper value, BUT, if the user uses "," as a decimal separator it will not work.
Possible solution that I can't make it work:
Get the user decimal separator in regional settings:
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
And make somehow the replace from ",",sepdec , that way it would stay a comma if its a comma, and replace by an actual dot if the user uses dots.
Hints?
Edit: Many users posted useful information, lately, using the arguments NumberStyles.Any, CultureInfo.GetCultureInfo("pt-PT") on a tryParse wouldn't work if your separator is set to "," So it pretty much doesnt fullfill the premise of making a tryparse "universal".
I'll work around this, if anyone has more hints you'r welcome
I know the thread is a little bit older, but I try to provide an answer.
I use regular expression to determine the used number format in the string.
The regex also matches numbers without decimal separators ("12345").
var numberString = "1,234.56"; // en
// var numberString = "1.234,56"; // de
var cultureInfo = CultureInfo.InvariantCulture;
// if the first regex matches, the number string is in us culture
if (Regex.IsMatch(numberString, #"^(:?[\d,]+\.)*\d+$"))
{
cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in de culture
else if (Regex.IsMatch(numberString, #"^(:?[\d.]+,)*\d+$"))
{
cultureInfo = new CultureInfo("de-DE");
}
NumberStyles styles = NumberStyles.Number;
bool isDouble = double.TryParse(numberString, styles, cultureInfo, out number);
HTH
Thomas
I just want to say that HTH Thomas solution worked really well in my project, except for when trying to parse negative decimal numbers with commas. One solution to this, which is probably not optimized because I don't fully understand the regex Ismatch code, but that works is adding the possibility of finding a "-" before the number in the ifs statements, like this:
var cultureInfo = CultureInfo.InvariantCulture;
if (Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[\d,]+\.)*\d+$") || Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[-\d,]+\.)*\d+$"))
{
cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in DE culture
if (Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[\d.]+,)*\d+$") || Regex.IsMatch(equation.inputFieldsTexts[i], #"^(:?[-\d.]+,)*\d+$"))
{
cultureInfo = new CultureInfo("de-DE");
}
The solution I use is to simply show the user what the parsed value is.
I have a custom TextBox control which verifies the input when the control loses focus and such. If the control expects a floating point value (which is a property), then it will try to parse the value entered. If the TryParse succeeds, I display the out value in the control's text.
This way, when a user enters 12.3 the value might change to 123 because in the current culture 12,3 is expected. It's then up to them to decide to correct this.
How about this method:
clean the string from anything else than numbers, dot, comma and negative sign
take the last index of dot or comma
split the clean string and remove all thousands separators from the first part
convert both parts to integer
change the sign of the second part if necessary
add the first part with the second part divided by decimal places
public static bool TryParseDoubleUniversal(this string s, out double result) {
result = 0.0;
if (string.IsNullOrEmpty(s)) return false;
var clean = new string(s.Where(x => char.IsDigit(x) || x == '.' || x == ',' || x == '-').ToArray());
var iOfSep = clean.LastIndexOfAny(new[] { ',', '.' });
var partA = clean.Substring(0, iOfSep).Replace(",", string.Empty).Replace(".", string.Empty);
var partB = clean.Substring(iOfSep + 1);
if (!int.TryParse(partA, out var intA)) return false;
if (!int.TryParse(partB, out var intB)) return false;
if (intA < 0) intB *= -1;
var dp = double.Parse("1".PadRight(partB.Length + 1, '0'));
result = intA + intB / dp;
return true;
}
The question is old but since it was my first hit on Google. And the approach in How to change symbol for decimal point in double.ToString()? seems to be a valid solution you can use the NumberFormatInfo to set the decimal separator like this:
string value = "3,2";
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalSeparator = ",";
decimal.TryParse(value, NumberStyles.Any, nfi, out decimal dec);
I found a solution, I'm a beginner on this regional and comma-dots theme so if you have comments to improve the understanding of this please be welcome.
We start of by getting what decimal separator the user has set in his regional options outside before the Form{InitializeComponent();} (I want a universal variable that will allow me to correct the code)
char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
In the tryParse, to get it to behave universally we will read the dots and commas in the string, and turn them into the decimal separator we defined as sepdec
decimal.TryParse(str.Replace(",",sepdec.ToString()).Replace(".",sepdec.ToString()), out somevariable);
I hope this helps, please comment improvement suggestions!
In Android Xamarin, I ran into the same issue several times. Some solutions worked until the Android got upgraded into a new version, then the problem came out again. So I came with an universal solution, which works fine. I read the numeric input as text, then parse it into decimal with a custom parser.
The custom parser is returning 0 when parsing into decimal is not possible. It does allow input text containing decimal number with either comma or dot, with no group separators:
public static decimal ParseTextToDecimal(string decimalText)
{
if (decimalText == String.Empty) return 0;
string temp = decimalText.Replace(',', '.');
var decText = temp.Split('.');
if (!Int32.TryParse(decText[0], out int integerPart)) return 0;
if (decText.Length == 1) return integerPart;
if (decText.Length == 2)
{
if (!Int32.TryParse(decText[1], out int decimalPart)) return 0;
decimal powerOfTen = 10m;
for (int i = 1; i < decText[1].Length; i++) powerOfTen *= 10;
return integerPart + decimalPart / powerOfTen;
}
return 0; // there were two or more decimal separators, which is a clear invalid input
}

Convert string to decimal but keep numeric portion

Is there a way to convert a string to decimal in C# but ignoring trailing "garbage"? i.e. like PHP's floatval() or C strtod() ?
e.g.
Convert string "2974.23abcdefs" to decimal 2974.23
As others have mentioned, there is no exact, like for like, replacement for what you can do in PHP and I think, for good reason. In the scenario of a web application, I'm not really sure that if I were accepting a decimal with garbage at the end, I'd actually want to consider that as valid data but this is just my opinion.
What you can do is define a regular expression that would capture the decimal and recognise that this is happening. I find this much safer and reliable.
Obviously, the regular expression can be improved but this is a simple example for you: -
var match = Regex.Match("2974.23abcdefs", "^([0-9]+\\.[0-9]+)(.+)?$");
if (match.Success)
{
// See the also the link below for using Decimal.TryParse
Console.WriteLine(Convert.ToDecimal(match.Groups[1].Value));
}
See https://msdn.microsoft.com/en-us/library/system.decimal.tryparse%28v=vs.110%29.aspx for my preferred way to convert to a decimal. This would ensure that you are coping with the output of the regular expression for how Decimal is comprised
For more information on regular expressions, see https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex%28v=vs.110%29.aspx
This works but only takes care of digits and the current culture's decimal-separator:
string input = "2974.23abcdefs";
decimal d;
char decSep = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator[0]; // there is no culture with a decimal-separator that has more than one letter so this isn't harmful
if(!string.IsNullOrEmpty(input) && Char.IsDigit(input[0]))
{
string number = string.Concat(input.TakeWhile(c => Char.IsDigit(c) || decSep == c));
bool validDecimal = decimal.TryParse(number, out d);
Console.WriteLine("Valid? {0} Parsed to: {1}", validDecimal, d);
}
Since we are using , as decimal separator here in germany i get a different result than people who use . as separator. You get 2974.23 and i get 2974.
As a first, second, third try, this should go:
static double Parse(string str, IFormatProvider provider = null)
{
if (str == string.Empty)
{
return 0;
}
if (provider == null)
{
provider = CultureInfo.CurrentCulture;
}
NumberFormatInfo nfi = NumberFormatInfo.GetInstance(provider);
// [ws][sign][integral-digits[,]]integral-digits[.[fractional-digits]][E[sign]exponential-digits][ws]
string ws = #"\s*";
string sign = #"(" + Regex.Escape(nfi.PositiveSign) + "|" + Regex.Escape(nfi.NegativeSign) + ")?";
string integralDigits1 = "([0-9](" + Regex.Escape(nfi.NumberGroupSeparator) + ")*)*";
string integralDigits2 = "[0-9]+";
string fractionalDigits = "(" + Regex.Escape(nfi.NumberDecimalSeparator) + "[0-9]*)?";
string exponentialDigits = "([Ee]" + sign + "[0-9]+)?";
var rx = new Regex(ws + sign + integralDigits1 + integralDigits2 + fractionalDigits + exponentialDigits);
string match = rx.Match(str).ToString();
if (match == string.Empty)
{
return 0;
}
return double.Parse(match, provider);
}
Note that the composed regex is very complex, because there are various "parts" in a full double that has been written to a string.
From MSDN:
[ws][sign][integral-digits[,]]integral-digits[.[fractional-digits]][E[sign]exponential-digits][ws]
Still some numbers will crash this function, if they are too much big. So passing new string('9', 1000) will make the double.Parse throw an exception.
Use it like:
double num = Parse(" +1,0.1234E+12abcdefgh", CultureInfo.InvariantCulture);
or
double num = Parse(" +1,,,,,0.1234E+12abcdefgh");
(if you don't need to configure the culture, will use the CultureInfo.CurrentCulture)
There are many ways to do so. I suggest using a Regex first, and then decimal.TryParse().
This is a regex that grabs a floating point number at the begin of the string, like -123.43 or just 1234.56 or 123456:
^([+-][0-9]+\.?[0-9]*).*$
Putting this into C# looks like this:
// Step 1: Getting some input
String input = "123.4533wefwe";
// Step 2: Get rid of the trail
Regex r = new Regex(#"^([+-][0-9]+\.?[0-9]*).*$", RegexOptions.IgnoreCase);
MatchCollection matches = r.Matches(input);
if (matches.Count > 0) {
Match match = matches[0];
GroupCollection groups = match.Groups;
// Step 3: create a real decimal from the string
decimal i;
NumberStyles style;
CultureInfo culture;
style = NumberStyles.Number;
culture = CultureInfo.CreateSpecificCulture("en-GB");
String matchedNumber = groups[1].Value;
if (decimal.TryParse(matchedNumber, style, culture, out i)) {
// Step 4: giving back the result:
Console.WriteLine("Parsed decimal: " + i);
}
}
The output of this is:
Parsed decimal: 123.4533
Remark: All this seems to become a bigger problem if you would like to parse real floating point number literals that include exponential notation. Then, severals stages of casting would be necessary.

How to replace a string with another

I'd like to make a program that isn't sensitive to the character , or . as input, in order to make some calculations without thinking about which symbol I should use to separate integer part from fractional part.
The only way i can imagine is to recognize the input string, check if there's a . and replace it with a , as my cultureType only accepts ,.
The problem is that I don't have any idea to make it, can someone help me?
if(inputString.Any(x => x == '.'))
{
inputString = inputString.Replace('.', ',');
}
I'm guessing (it's not in your question) that you're trying to parse a decimal, and the number may have a decimal separator and no thousand separator, and it might be a , and it might be a . A possible heuristic to guess which one it is, is to check the last occurrence of either.
That could be done by
string input = "123.456.496,58"; //or 123,456,789.58
int lastComma = input.LastIndexOf(",");
int lastPeriod = input.LastIndexOf('.');
NumberFormatInfo format = new NumberFormatInfo();
if (lastComma > lastPeriod) {
format.NumberDecimalSeparator = ',';
format.NumberGroupSeparator = '.';
} else {
format.NumberDecimalSeparator = '.';
format.NumberGroupSeparator = ',';
}
double parsed = Double.Parse(intput, format);
this fails when there is a group separator after the decimal separator, and other heurisics could be employed to change it (i.e. if there is only one non-numeric character, that one is the decimal separator. If there are multiple non-numeric special characters, and one of them only occurs once, that is the decimal separator)
In the end parsing a string with an unknown format will require some guesswork.
If you're not trying to parse numbers, but are doing something different entirely, disregard this answer, and pick one of the others.
if (yourString.Contains(".")) { youString = yourString.Replace(".", ","); }

How can I convert formatted string to int (if I know format) in C#?

I have formatted string, for example 123 456 000$ and I know format of this string {0:### ### ##0}$. I'd like to get int value = 123456000; from this string in C# with using known format.
How I can do that?
mytext = System.Text.RegularExpressions.Regex.Replace(mytext.Name, "[^.0-9]", "");
or something approximately like that get's rid of the pesky non-numbers
and then delete the first few characters 1,2,3... and last few length, length -1, length -3...
unless I'm missing something?
Oh yeah, and Convert.Toint32(mytext)
int.Parse("123 456 000$", NumberStyles.AllowCurrencySymbol |
NumberStyles.Number);
http://msdn.microsoft.com/en-us/library/c09yxbyt.aspx
I think you will have to construct a similar NumberFormatInfo to parse the string value.$ for the currency symbol used in the text and in your case the thousand group seperator is space instead of , so a custom number format info should help you parse it.
string val = "123 456 000$";
NumberFormatInfo numinf = new NumberFormatInfo();
numinf.CurrencySymbol = "$";
numinf.CurrencyGroupSeparator = " ";
numinf.NumberGroupSeparator = " "; // you have space instead of comma as the seperator
int requiredval = int.Parse(val,NumberStyles.AllowCurrencySymbol | NumberStyles.AllowThousands, numinf);
This should help you get the value
I would make it easy way:
String formattedString = "12345500$";
formattedString.Remove(formattedString.Length - 1);
int value = int.Parse(formattedString);

Categories