[英]Avoid decimal.TryParse to recognize “1.1.1” or “1,1,1” as decimal
我在字符串識別方面有一個問題:我試圖僅以正確的格式識別數字,但找不到方法。
我正在寫一種文化不變的方式,因此我需要識別“,”和“”。 作為十進制和千位分隔符,反之亦然。
所有這些對我來說都是正確的格式:
12,1
12.1
1.000,12
1,000.12
但是這樣的事情是錯誤的
1.2.3
1,2,3
我試過了:
NumberStyles style;
decimal n;
object valore;
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowThousands;
Console.WriteLine(decimal.TryParse(valore.ToString(), style , CultureInfo.InvariantCulture, out n));
但是“ 1,1,1”被讀取為有效數字,而“ 1.1.1”則無效。
如果我使用特定的區域性(“ it-IT”),則可以識別“ 1,1,1”,而不能識別“ 1.1.1”。
如何丟棄所有無效字符串?
我最后以個人解析器結束了此事,希望找到更好的解決方案,但閱讀評論似乎不太可能
public static bool tryValoreNumerico(object valore, out decimal valoreRestituito)
{
decimal n;
string testoNormalizzato;
valoreRestituito = 0;
// normalizzazione
if (valore.ToString().Contains(",") && valore.ToString().Contains("."))
{
if (valore.ToString().IndexOf(".") < valore.ToString().IndexOf(","))
{
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
{
testoNormalizzato = valore.ToString().Replace(",", "");
}
}
else
{
if ((valore.ToString().Length - valore.ToString().Replace(",", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split(',');
for (int i = 1; i < pezzi.Length; i++ )
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(",", "");
}
else if ((valore.ToString().Length - valore.ToString().Replace(".", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split('.');
for (int i = 1; i < pezzi.Length; i++)
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
testoNormalizzato = valore.ToString();
}
testoNormalizzato = testoNormalizzato.Replace(",", ".");
if (decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", "."))
{
valoreRestituito = Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US"));
}
return decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", ".");
}
簡而言之,我首先將數字標准化為EN格式,然后嘗試將其轉換
最后一個測試是看到沒有與數字相似的文本,因為諸如“ 001”,“ 100 01”之類的字符串不是數字。
比率是:每個字符串都必須保持不變:轉換為數字的“ 001”變為不同於原始值的“ 1”,因此必須避免這種轉換
我建議您使用Regex
進行驗證和類似這樣的自定義解析方法:
public static decimal DecimalParse(string number)
{
if (new Regex(@"^\d+$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
if (new Regex(@"^(\d{0,3}(,\d{3})*(\.\d+)?)$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
return new Regex(@"^(\d{0,3}(\.\d{3})*(,\d+)?)$").IsMatch(number)
? decimal.Parse(number.Replace(".", "").Replace(",", "."), CultureInfo.InvariantCulture)
: 0;
}
結果將是:
string num;
num = "1,000"; Console.WriteLine("{0}", DecimalParse(num)); //1000
num = ",01"; Console.WriteLine("{0}", DecimalParse(num)); //0.01
num = ".02"; Console.WriteLine("{0}", DecimalParse(num)); //0.02
num = "12,1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "12.1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "1.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1.000.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1,000,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1000"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110."; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110,"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1.2.3"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1,2,3"; Console.WriteLine("{0}", DecimalParse(num)); //0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.