C'è un modo per rendere le funzioni C# TryParse()
un po 'più ... severe?decimal.TryParse accetta volentieri le stringhe numeriche formattate male
In questo momento, se si passa in una stringa contenente numeri, i corretti decimali & mille caratteri di separazione, spesso sembra solo ad accettarle, anche se il formato non ha senso, ad esempio: 123''345'678
I Sto cercando un modo per rendere TryParse
senza successo se il numero non è nel formato giusto.
Quindi, sto con sede a Zurigo, e se faccio questo:
decimal exampleNumber = 1234567.89m;
Trace.WriteLine(string.Format("Value {0} gets formatted as: \"{1:N}\"", exampleNumber, exampleNumber));
... poi, con le mie impostazioni internazionali, ottengo questo ...
Value 1234567.89 gets formatted as: "1'234'567.89"
Così puoi vedere che, per la mia regione, il carattere decimale è un punto e il mille separatore è un apostrofo.
Ora, creiamo una semplice funzione per verificare se un string
può essere analizzato in un decimal
:
private void ParseTest(string str)
{
decimal val = 0;
if (decimal.TryParse(str, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
Va bene, chiamiamo questa funzione con alcune stringhe.
Quale delle seguenti stringhe sarebbe si pensa che venga analizzato correttamente da questa funzione?
Qui di seguito sono i risultati che ho ottenuto:
ParseTest("123345.67"); // 1. Parsed "123345.67" as 123345.67
ParseTest("123'345.67"); // 2. Parsed "123'345.67" as 123345.67
ParseTest("123'345'6.78"); // 3. Parsed "123'345'6.78" as 1233456.78
ParseTest("1''23'345'678"); // 4. Parsed "1''23'345'678" as 123345678
ParseTest("'1''23'345'678"); // 5. Couldn't parse: "'1''23'345'678"
ParseTest("123''345'678"); // 6. Parsed "123''345'678" as 123345678
ParseTest("123'4'5'6.7.89"); // 7. Couldn't parse: "123'4'5'6.7.89"
ParseTest("'12'3'45'678"); // 8. Couldn't parse: "'12'3'45'678"
penso che si può vedere il mio punto.
Per me, solo le prime due stringhe avrebbero dovuto analizzare correttamente. Gli altri dovrebbero aver fallito tutti, dato che non hanno 3 cifre dopo mille separatori, o hanno due apostrofi insieme.
Anche se cambio lo ParseTest
in modo un po 'più specifico, i risultati sono esattamente gli stessi. (Per esempio, accetta felicemente "123''345'678
" come un decimale valido.)
private void ParseTest(string str)
{
decimal val = 0;
var styles = (NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands);
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
Trace.WriteLine(string.Format("Parsed \"{0}\" as {1}", str, val));
else
Trace.WriteLine(string.Format("Couldn't parse: \"{0}\"", str));
}
Quindi, c'è un modo semplice per non consentono stringhe formattate male per essere accettato da TryParse
?
Aggiornamento
Grazie per tutti i suggerimenti.
Forse dovrei chiarire: quello che sto cercando è che le prime due stringhe siano valide, ma la terza deve essere rifiutata.
ParseTest("123345.67");
ParseTest("123'456.67");
ParseTest("12'345'6.7");
Sicuramente ci deve essere un modo per utilizzare "NumberStyles.AllowThousands
" in modo che possa consentire opzionalmente mille-separatori, ma assicurarsi che il formato numerico fa ha senso?
In questo momento, se uso questo:
if (decimal.TryParse(str, styles, CultureInfo.CurrentCulture, out val))
ottengo questi risultati:
Parsed "123345.67" as 123345.67
Parsed "123'456.67" as 123456.67
Parsed "12'345'6.7" as 123456.7
E se uso questo:
if (decimal.TryParse(str, styles, CultureInfo.InvariantCulture, out val))
ottengo questi risultati:
Parsed "123345.67" as 123345.67
Couldn't parse: "123'456.67"
Couldn't parse: "12'345'6.7"
Questo è il mio problema ... indipendentemente dalle impostazioni di CultureInfo, la terza stringa deve essere rifiutata e le prime due accettate.
Devi accettare * valido * migliaia di separatori? In caso contrario, non utilizzare AllowThousands ... –
Sembra che sia necessaria una convalida di espressioni regolari separata. –
Onestamente, sono sorpreso che adiacente a migliaia i separatori vengano analizzati con successo _even_ quando si assegna la proprietà corretta nell'esempio '123''345'678'. Ma forse hai solo bisogno di assegnare la proprietà 'NumberGroupSizes' come' {3, 3, 0} 'in questo caso. Non lo so. –