I need to extract a variable length decimal number from a string using c# and .NET. The input string is like $PTNTHPR,352.5,N,2.3,N,4.6,N,16*. I need the first occurrence of decimal number, i.e the 352.5 part. The numerical value ranges from 0.0 to 360.0 and I need that number from that string.
I searched a lot and got solution for a fixed length sub string but here I have variable length to extract. I have not tried with any code yet.
If it is always in this format you can use String.Split and decimal.Parse
var data = #"$PTNTHPR,352.5,N,2.3,N,4.6,N,16*";
var d = decimal.Parse(data.Split(new[]{','})[1]);
Console.WriteLine(d);
This is just a sample code to guide you. You should add additional exception handling logic to this, Also consider using decimal.TryParse
If you want to find the first occurance of decimal value you split the string and parse them one by one.
var data = #"$PTNTHPR,352.5,N,2.3,N,4.6,N,16*";
var splited = data.Split(new[]{','});
decimal? value = null;
foreach (var part in splited)
{
decimal parsed;
if (decimal.TryParse(part, out parsed))
{
value = parsed;
break;
}
}
Console.WriteLine(value);
First occurence in any of the tokens? Use String.Split to separate them and LINQ to find the first. You can use decimal.TryParse to check if it's parsable:
decimal? firstParsableToken = "$PTNTHPR,352.5,N,2.3,N,4.6,N,16*".Split(',')
.Select(s => s.TryGetDecimal(NumberFormatInfo.InvariantInfo))
.FirstOrDefault(d => d.HasValue);
Used this simple extension method to parse it to decimal?:
public static decimal? TryGetDecimal(this string item, IFormatProvider formatProvider = null, NumberStyles nStyles = NumberStyles.Any)
{
if (formatProvider == null) formatProvider = NumberFormatInfo.CurrentInfo;
decimal d = 0m;
bool success = decimal.TryParse(item, nStyles, formatProvider, out d);
if (success)
return d;
else
return null;
}
If the string is always comma separated, can you not use string.Split() to get each section, then use double.TryParse() to test if that part is numeric?
public static class Helper
{
public static string MyExtract(this string s)
{
return s.Split(',').First(str => Regex.IsMatch(str, #"[0-9.,]"));
}
}
Use it like this: string str = "$PTNTHPR,352.5,N,2.3,N,4.6,N,16*".MyExtract();
Then convert it to double/decimal if you need it.
Related
I've tried three approaches to get a ProperName solution for a string of all CAPS.
Here is my code:
string testStr = "SYNDEGAARD";
string result1 = UppercaseFirst(testStr);
string titleCase = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(testStr);
string result2 = titleCase;
CultureInfo culture_info = Thread.CurrentThread.CurrentCulture;
TextInfo text_info = culture_info.TextInfo;
string result3 = text_info.ToTitleCase(testStr);
private static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}
All three results are "SYNDENGAARD". It never changes to "Syndengaard".
The reason why you can't get the result you wanted is because ToTitleCase() doesn't work if the input string is all in capital letters.
You can try changing SYNDEGAARD to SYNDEGAARDx and see the difference.
As to why that's the default behavior I am not sure.
Also you forgot to add ToLower() in this function to make sure that the preceding texts will be in lowercase.
private static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1).ToLower(); // Missing ToLower()
}
EDIT:
Here's why nothing happens for uppercase texts.
TextInfo.ToTitleCase Method (String).
Converts the specified string to title case (except for words that are
entirely in uppercase, which are considered to be acronyms).
Use Humanizer, it will provide you with the range of utilities for conversions and manipulate strings, enums, dates, times, timespans, numbers and quantities.
https://github.com/Humanizr/Humanizer
Nuget Package
https://www.nuget.org/packages/Humanizer/
Var name = "shyam bhagat";
var titleCase = name.Humanize(LetterCasing.Title);
Just update to this
return char.ToUpper(s[0]) + s.Substring(1).ToLower();
This might be a very simple question.
Suppose text box show value 10,000.12 when user edits data by mistake he remove first two numbers like ,000.12 and using this textbox in the calculation then it gives an exception. I want a just validate text box.
For Example:
string str = ",100.12;"
Convert to
decimal number = 100.12;
Any Idea?.
It shows only whole number when user remove any thousand separator.
This is pretty messed up and I am not sure if all of you strings will look the same, but in case they do this might do the trick:
string str = ",0,100.12";
decimal number;
bool converted = decimal.TryParse(str.Substring(str.LastIndexOf(",") + 1), out number);
The variable converted will tell you whether or not your string was converted and you will not an exception.
Good luck!
If I understood the question, you want to remove all characters that would prevent the parse routine from failing.
string str = ",0,100.12";
var modified = new StringBuilder();
foreach (char c in str)
{
if (Char.IsDigit(c) || c == '.')
modified.Append(c);
}
decimal number= decimal.Parse(modified.ToString());
string a = "100.12";
decimal b = Convert.ToDecimal(a);
string str = ",0,100.12;";
var newstr = Regex.Replace(str,#"[^\d\.]+","");
decimal d = decimal.Parse(newstr, CultureInfo.InvariantCulture);
I want to find which Currency Symbol exists in Currency Format data.
For example, Input String = $56.23
public class FormatConverter
{
private CultureInfo _cultureInfo;
public void UpdateCultureInfo()
{
Thread.CurrentThread.CurrentCulture.ClearCachedData();
var thread = new Thread(
s => _cultureInfo = Thread.CurrentThread.CurrentCulture);
thread.Start();
thread.Join();
}
Bool TryParseCurrencySymbolAndValue(string input, out string CurrencySymbol,
out double value)
{
if(_cultureInfo == null)
UpdateCultureInfo();
try{
// Convert Currency data into double
value = Double.Parse(input, NumberStyles.Number | NumberStyles.AllowCurrencySymbol);
// How to extract Currency Symbol?
CurrencySymbol = "$";
return true;
}
catch(Exception ex){ /* Exception Handling */}
return false;
}
}
I want to extract "$" symbol from a string and 56.23 separately and then I want to apply CultureInfo to 56.23 into French Format. The output should be $56,23.
In some cases, input might be "Euro sign" or some other currency symbol in the beginning or in the end of input string.
I know how to convert into CurrentCulture for Numeric part. I don't know how to extract currency Symbol from a string.
It sounds like you already know how to parse the string into a number type (correct me if I'm wrong). You're using double in your example, I would suggest decimal but that's your choice.
To get the currency symbol you can use a simple regular expression
Regex ex = new Regex(#"\p{Sc}");
CurrencySymbol = ex.Match(input).Value;
I hope that helps.
Look at this link as well to give you and idea as to the many different ways you can find and or use IndexOf
[IndexOf String Examples][1]
the question is will the format always have the $ as the first char..? if the answer is yes
regardless of USC or Foreign Currency use the String.IndexOf Method
String.IndexOf("$")
here is a coded example that you may look at
using System;
class Program
{
static void Main()
{
// A.
// The input string.
const string s = "Tom Cruise is an Idiot he should pay $54.95.";
// B.
// Test with IndexOf.
if (s.IndexOf("$") != -1)
{
Console.Write("string contains '$'");
}
Console.ReadLine();
}
}
Output
string contains '$'
Can you please try with?
float curSymbol;
bool isValid = float.TryParse(curValue,
NumberStyles.Currency,
CultureInfo.GetCultureInfo("en-US"), out curSymbol);
Get the curSymbol. :) Be sure to pass currency values with symbol:)
I would like to convert a string to double (very basic question isn't it ?)
string input = "45.00000";
double numberd = Double.Parse(input, CultureInfo.InvariantCulture);
=> my code works and I am very happy.
However I may have the following
string input = "";
double numberd = Double.Parse(input, CultureInfo.InvariantCulture);
In this case my code does not work and I get a Exception error ;(
I wonder how I can manage such situation. Ideally when I get this I would like to have my variable numberd equal to null.
Can anyone help me ?
Thx
Microsoft recommends using the Tester-Doer pattern as follows:
string input = "";
double numberd;
if( Double.TryParse(input, out numberd) )
{
// number parsed!
}
Use a Double for parsing, but a Double? for storing the value, perhaps?
Double number;
string input = ""; // just for demo purpose, naturally ;o)
Double? nullableNumber =
Double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out number)
? (Double?)number
: null;
// use nullableNumber
Primitive types like double cannot be null. You can have a nullable version with double? but, Double.Parse does not return a double? (just a plain double).
You could use Double.TryParse and check the return condition and set a double? to null accordingly if that would suit better.
Why not just catch the exception and set your variable?
double numberd;
try {
numberd = Double.Parse(input, CultureInfo.InvariantCulture);
} catch (System.FormatException e)
numberd = 0.0;
}
Alternatively, you can use Double.TryParse
Add an if statement comparing strings or surround with try/catch block.
Assuming you aren't worried about other invalid values besides empty strings, here's a simple one-liner:
Double? numberd = (input.Length == 0) ? null : (Double?)Double.Parse(input, CultureInfo.InvariantCulture);
mzabsky was on the right path, however his solution won't build and you shouldn't hard-code empty string - it's better to check the length of a string.
How about
Double? numberd = String.IsNullOrEmpty(str) ? null : Double.Parse(str)
In my application, I am parsing CSV files and I want these empty strings to be zero so I return 0.0 instead of null and it's all good.
5 more
What is the best way to convert any currency into decimal in C#?
public static decimal returnDecimalFromCurrency(string dataToCheck) {
decimal varValue;
if (!Decimal.TryParse(dataToCheck, NumberStyles.Number | NumberStyles.AllowCurrencySymbol, CultureInfo.CurrentCulture, out varValue)) {
varValue = decimal.MinValue;
}
return varValue;
}
But this one does work for only my current currency. If i pass it EURO currency it won't get converted.
Or the only way is to always check what currency it is and pass proper CultureInfo:
CultureInfo.GetCultureInfo("pl-PL") for zl, or CultureInfo.GetCultureInfo("en-GB") for pounds?
Edit:
Or maybe this is the quick "working" hack?
Decimal.TryParse(dataToCheck.Trim().Replace("zł", "").Replace("€", ""), NumberStyles.Number | NumberStyles.AllowCurrencySymbol, CultureInfo.GetCultureInfo("pl-PL"), out varValue)
But to be honest I don't really like it.
I'd avoid trying to parse the currency with Decimal.TryParse and instead strip off the currency - giving the resultant string to TryParse. Deal with the currency separately - of course, create a function to do this if you need to do it more than once.
Here 's what works for me, I hope it helps you too:
public static decimal Parse(string currencyString)
{
return Parse(currencyString, Thread.CurrentThread.CurrentCulture);
}
public static decimal Parse(string currencyString, CultureInfo culture)
{
currencyString = currencyString.Replace(culture.NumberFormat.CurrencySymbol, System.String.Empty);
var value = Convert.ToDecimal(currencyString, culture);
return value;
}
I solved this same problem with a hybrid approach. The regex to ignore period, comma, parenthesis (in my case I know negatives are in parenthesis), and digits is fairly simple. Just use that to find your symbol, and then build a culture from it. Then parse.
//[^\d\.,()]+ all non-digit, non-period, non-comma, non-parenthesis chars
var regex = new Regex("[^\\d\\.,()]+");
var match = regex.Match(currencyString);
if(match == null){ //throw exception }
var currencySymbol = match.Value;
var cultureInfo = Thread.CurrentThread.CurrentCulture.Clone() as CultureInfo;
cultureInfo.NumberFormat.CurrencySymbol = currencySymbol;
var decimalValue = Decimal.Parse(currencyString, NumberStyles.Currency, cultureInfo);
I ran into this issue today, and I ended up just looping through all of the cultures, and passing each one to the TryParse function.
var myString = "$400.01";
var result = 0.0m;
var culture = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures)
.First(c => decimal.TryParse(myString, System.Globalization.NumberStyles.Currency, c, out value))
// result = 400.01m