Devo convalidare un input textbox
e posso solo consentire input decimali come: X,XXX
(solo una cifra prima del segno decimale e una precisione di 3).Espressione regolare per numero decimale
Sto usando C# e prova questo ^[0-9]+(\.[0-9]{1,2})?$
?
Devo convalidare un input textbox
e posso solo consentire input decimali come: X,XXX
(solo una cifra prima del segno decimale e una precisione di 3).Espressione regolare per numero decimale
Sto usando C# e prova questo ^[0-9]+(\.[0-9]{1,2})?$
?
^[0-9]([.,][0-9]{1,3})?$
Permette:
0
1
1.2
1.02
1.003
1.030
1,2
1,23
1,234
MA NON:
.1
,1
12.1
12,1
1.
1,
1.2345
1,2345
Sostituendo [0-9] con \ d taglia 3 caratteri (6 totali) e fa la stessa cosa. – UnkwnTech
+1 ma non sarebbe bello accettare .1 poiché questa è una rappresentazione valida di 0.1 (testata con Decimal.Parse)? – stevehipwell
La versione più semplice di questo sarebbe "\ d (\. \ D {1,3})?" ma usando "\ d (?: \. \ d {1,3})?" significherà che un gruppo non è memorizzato. – stevehipwell
\d{1}(\.\d{1,3})?
Match a single digit 0..9 «\d{1}»
Exactly 1 times «{1}»
Match the regular expression below and capture its match into backreference number 1 «(\.\d{1,3})?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Match the character “.” literally «\.»
Match a single digit 0..9 «\d{1,3}»
Between one and 3 times, as many times as possible, giving back as needed (greedy) «{1,3}»
Created with RegexBuddy
Partite:
1,2
1,23
1 .234
puoi anche escludere {1} – tanascius
l'ho capito e modificato per riflettere la modifica. – UnkwnTech
Hai ancora \ d {1} invece di \ d – stevehipwell
C'è un approccio alternativo, che non ha problemi I18n (che consente "," o "." Ma non entrambi): Decimal.TryParse
.
Prova a convertire, ignorando il valore.
bool IsDecimalFormat(string input) {
Decimal dummy;
return Decimal.TryParse(input, out dummy);
}
Questo è significativamente più veloce rispetto all'uso di un'espressione regolare, vedere di seguito.
(Il sovraccarico di Decimal.TryParse
può essere utilizzato per un controllo più preciso.)
prestazioni i risultati dei test: Decimal.TryParse: 0.10277ms, Regex: 0.49143ms
Codice (PerformanceHelper.Run
è un aiuto di corre il delegato per il conteggio di iterazione passato e restituisce la media TimeSpan
):.
using System;
using System.Text.RegularExpressions;
using DotNetUtils.Diagnostics;
class Program {
static private readonly string[] TestData = new string[] {
"10.0",
"10,0",
"0.1",
".1",
"Snafu",
new string('x', 10000),
new string('2', 10000),
new string('0', 10000)
};
static void Main(string[] args) {
Action parser =() => {
int n = TestData.Length;
int count = 0;
for (int i = 0; i < n; ++i) {
decimal dummy;
count += Decimal.TryParse(TestData[i], out dummy) ? 1 : 0;
}
};
Regex decimalRegex = new Regex(@"^[0-9]([\.\,][0-9]{1,3})?$");
Action regex =() => {
int n = TestData.Length;
int count = 0;
for (int i = 0; i < n; ++i) {
count += decimalRegex.IsMatch(TestData[i]) ? 1 : 0;
}
};
var paserTotal = 0.0;
var regexTotal = 0.0;
var runCount = 10;
for (int run = 1; run <= runCount; ++run) {
var parserTime = PerformanceHelper.Run(10000, parser);
var regexTime = PerformanceHelper.Run(10000, regex);
Console.WriteLine("Run #{2}: Decimal.TryParse: {0}ms, Regex: {1}ms",
parserTime.TotalMilliseconds,
regexTime.TotalMilliseconds,
run);
paserTotal += parserTime.TotalMilliseconds;
regexTotal += regexTime.TotalMilliseconds;
}
Console.WriteLine("Overall averages: Decimal.TryParse: {0}ms, Regex: {1}ms",
paserTotal/runCount,
regexTotal/runCount);
}
}
Non solo è più veloce, è molto più pulito. –
ho appena trovato TryParse()
ha un problema che rappresenta migliaia di separatori. Esempio in En-US, 10,36,00 è ok. Ho avuto uno scenario specifico in cui il separatore di migliaia non dovrebbe essere considerato e quindi l'espressione regolare \d(\.\d)
risulta essere la migliore. Ovviamente doveva mantenere la variabile decimale char per diverse localizzazioni.
Usa il sovraccarico di 'Decimal.TryParse' che accetta un parametro' NumerStyles', e * non * include 'NumerStyles.AllowThousands'. – Richard
Mentre mi azzardo, TryParse in 3.5 ha NumberStyles: Il seguente codice dovrebbe anche fare il trucco senza che Regex ignori il separatore di migliaia.
double.TryParse(length, NumberStyles.AllowDecimalPoint,CultureInfo.CurrentUICulture, out lengthD))
Non pertinente alla domanda originale posta ma conferma che TryParse() è davvero una buona opzione.
In generale, vale a dire posti decimali illimitate:
^-?(([1-9]\d*)|0)(.0*[1-9](0*[1-9])*)?$
In .NET, vi consiglio di creare dinamicamente l'espressione regolare con il separatore decimale del contesto culturale attuale:
using System.Globalization;
...
NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo;
Regex re = new Regex("^(?\\d+("
+ Regex.Escape(nfi.CurrencyDecimalSeparator)
+ "\\d{1,2}))$");
Potresti voler sfruttare l'espressione regolare, consentendo separatori 1000er allo stesso modo del separatore decimale.
Perché dovresti usare le espressioni regolari qui invece della soluzione framework ('decimal.TryParse')? –