入力を検証する必要があり、次のtextbox
ような小数入力のみを許可できますX,XXX
(小数点の前に 1 桁のみ、精度は 3 です)。
私はC#を使用していますが、これを試してみてください^[0-9]+(\.[0-9]{1,2})?$
?
^[0-9]([.,][0-9]{1,3})?$
以下が可能です。
0
1
1.2
1.02
1.003
1.030
1,2
1,23
1,234
だがしかし:
.1
,1
12.1
12,1
1.
1,
1.2345
1,2345
I18n の問題がない別の方法があります (「,」または「.」は許可されますが、両方は許可されません) Decimal.TryParse
。
値を無視して変換してみてください。
bool IsDecimalFormat(string input) {
Decimal dummy;
return Decimal.TryParse(input, out dummy);
}
これは、正規表現を使用するよりも大幅に高速です。以下を参照してください。
(のオーバーロードはDecimal.TryParse
、より細かい制御に使用できます。)
パフォーマンス テストの結果: Decimal.TryParse: 0.10277ms、Regex: 0.49143ms
コード (PerformanceHelper.Run
は、渡された反復カウントのデリゲートを実行し、平均を返すヘルパーです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);
}
}
\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
一致:
1
1.2
1.23
1.234
一般に、つまり無制限の小数点以下の桁数:
^-?(([1-9]\d*)|0)(.0*[1-9](0*[1-9])*)?$
TryParse()
千単位の区切り記号を説明するという問題があることがわかりました。En-US の例では、10,36.00 で問題ありません。千単位の区切り記号を考慮すべきではない特定のシナリオがあったため、正規表現\d(\.\d)
が最善の策であることが判明しました。もちろん、異なるロケール用に 10 進数の char 変数を保持する必要がありました。
私がこれに苦労したとき、3.5 の TryParse には NumberStyles があります。
double.TryParse(length, NumberStyles.AllowDecimalPoint,CultureInfo.CurrentUICulture, out lengthD))
元の質問とは関係ありませんが、TryParse() が実際に適切なオプションであることを確認します。