Analisar strings para duplicar com vírgula e ponto

Eu estou tentando escrever uma function que basicamente converte uma matriz de seqüências de caracteres para uma matriz de seqüências de caracteres onde todos os duplos na matriz são arredondados para o número de casas decimais que eu defino. Também pode haver cadeias na matriz que não são valores duplos.

string[,] values = new string[1, 3]; values[0, 0] = "hello"; values[0, 1] = "0.123"; values[0, 2] = "0,123"; int decimalPlaces = 2; double tmp; string format = "F" + decimalPlaces.ToString(); IFormatProvider provider = CultureInfo.InvariantCulture; for (int i = 0; i < values.GetLength(0); i++) { for (int j = 0; j < values.GetLength(1); j++) { if (double.TryParse(values[i, j], out tmp)) { values[i, j] = tmp.ToString(format, provider); } } } Console.ReadLine(); 

O resultado tem que ser: “hello”, “0.12”, “0.12” mas é “olá”, “123.00”, “0.12” tratará a vírgula da maneira errada. Alguém tem uma solução simples e eficiente para isso?

Você quer tratar ponto ( . ) Como vírgula ( , ). Então, substitua

 if (double.TryParse(values[i, j], out tmp)) 

com

 if (double.TryParse(values[i, j].Replace('.', ','), out tmp)) 

Para tratar ambos e. como ponto decimal, você deve não apenas replace um pelo outro, mas também certificar-se de que a análise usada pela Cultura o interpreta como um ponto decimal.

 text = text.Replace(',', '.'); return double.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out value); 

Você não precisa replace a vírgula e ponto ..

Eu tive o mesmo problema. A razão é simples, a cultura de conversão desempenha um grande papel no qual a vírgula ou um ponto é interpretado. Eu uso uma cultura alemã onde a vírgula distingue as frações, onde, como em outros lugares, o ponto faz o trabalho.

Aqui fiz um exemplo completo para esclarecer a diferença.

 string[] doubleStrings = {"hello", "0.123", "0,123"}; double localCultreResult; foreach (var doubleString in doubleStrings) { double.TryParse(doubleString, NumberStyles.Any, CultureInfo.CurrentCulture, out localCultreResult); Console.WriteLine(string.Format("Local culture results for the parsing of {0} is {1}",doubleString,localCultreResult)); } double invariantCultureResult; foreach (var doubleString in doubleStrings) { double.TryParse(doubleString, NumberStyles.Any, CultureInfo.InvariantCulture, out invariantCultureResult); Console.WriteLine(string.Format("Invariant culture results for the parsing of {0} is {1}", doubleString, invariantCultureResult)); } 

os resultados onde os seguintes insira a descrição da imagem aqui

Brinque com a cultura e você terá o resultado que você precisa.

O problema é que você (ou o sistema) não consegue distinguir um separador decimal de um separador de milhares quando eles podem ser tanto uma vírgula quanto um ponto. Por exemplo:

Na minha cultura

1.123 é uma notação normal para um número acima de 1000; enquanto que

1,123 é um número próximo de 1.

Usando a cultura invariável, o padrão é usar o ponto como um separador decimal. Em geral, você deve garantir que todos os números sejam escritos usando a mesma cultura constante em todos os sistemas (por exemplo, a cultura invariável).

Se você tem certeza de que seus números nunca contêm nada além de uma vírgula ou ponto para um separador decimal (ou seja, sem separadores de milhares), eu String.Replace() a vírgula com um ponto e faço o resto como você fez.

Caso contrário, você terá dificuldade em programar algo que possa distinguir 1.123 de 1,123 sem conhecer a cultura.

Extensão para analisar o número decimal da cadeia.

  • Não importa o número será no começo, no final, ou no meio de uma string.
  • Não importa se haverá apenas um número ou muitas letras “lixo”.
  • Não importa o que é delimitador configurado nas configurações culturais no PC: ele irá analisar ponto e vírgula corretamente.
  • Capacidade de definir o símbolo decimal manualmente.

     public static class StringExtension { public static double DoubleParseAdvanced(this string strToParse, char decimalSymbol = ',') { string tmp = Regex.Match(strToParse, @"([-]?[0-9]+)([\s])?([0-9]+)?[." + decimalSymbol + "]?([0-9 ]+)?([0-9]+)?").Value; if (tmp.Length > 0 && strToParse.Contains(tmp)) { var currDecSeparator = System.Windows.Forms.Application.CurrentCulture.NumberFormat.NumberDecimalSeparator; tmp = tmp.Replace(".", currDecSeparator).Replace(decimalSymbol.ToString(), currDecSeparator); return double.Parse(tmp); } return 0; } } 

Como usar:

 "It's 4.45 O'clock now".DoubleParseAdvanced(); // will return 4.45 "It's 4,45 O'clock now".DoubleParseAdvanced(); // will return 4.45 "It's 4:45 O'clock now".DoubleParseAdvanced(':'); // will return 4.45 

Você pode verificar se a string contém um ponto decimal usando

string s="";

  if (s.Contains(',')) { //treat as double how you wish } 

e, em seguida, tratar isso como um decimal, caso contrário, basta passar o valor não duplo ao longo.

Use essa sobrecarga de double.TryParse para especificar os formatos permitidos:

Método Double.TryParse (String, NumberStyles, IFormatProvider, Double%)

Por padrão, double.TryParse será analisado com base nos formatos específicos da cultura atual.

tente isso … funciona para mim.

 double vdouble = 0; string sparam = "2,1"; if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) ) { if ( sparam.IndexOf( '.' ) != -1 ) { sparam = sparam.Replace( '.', ',' ); } else { sparam = sparam.Replace( ',', '.' ); } if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) ) { vdouble = 0; } }