【问题标题】:Validate float number using RegEx in C#在 C# 中使用 RegEx 验证浮点数
【发布时间】:2012-02-02 05:38:41
【问题描述】:

我正在尝试在 WPF 中仅创建一个数字 TextBox,并且我有以下代码:

void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = !IsValidInput(e.Text);
}

private bool IsValidInput(string p)
{
    switch (this.Type)
    {
        case NumericTextBoxType.Float:
            return Regex.Match(p, "^[0-9]*[.][0-9]*$").Success;
        case NumericTextBoxType.Integer:                    
        default:
            return Regex.Match(p, "^[0-9]*$").Success;                    
    }
}

// And also this!
public enum NumericTextBoxType
{
    Integer = 0, 
    Float = 1
}

当我将类型设置为 Integer 时,它工作得很好,但对于 Float,它就不行了。

我可以使用这么多NumericTextBox 控件,但我想知道为什么这个不起作用?

【问题讨论】:

  • 具体在什么情况下不起作用?
  • 对于Integer,它接受整数,但对于Float,它只接受一个句点.
  • 看起来 Double.TryParse 会更好地工作...但与 RegExp 相比,乐趣要少得多...

标签: c# wpf regex validation


【解决方案1】:

试试这个:

@"^[0-9]*(?:\.[0-9]*)?$"

你需要逃离这个时期。将句点和小数部分设为可选可能是个好主意。

如果您需要处理负值,您可以在每个模式中的第一个 [0-9] 之前添加 -?

更新

测试如下:

var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
Console.WriteLine(new bool[] {regex.IsMatch("blah"),
                              regex.IsMatch("12"),
                              regex.IsMatch(".3"),
                              regex.IsMatch("12.3"),
                              regex.IsMatch("12.3.4")});

结果

False 
True 
True 
True 
False 

【讨论】:

  • 干得好,但为什么非捕获组(?:)?此外,您不需要在正则表达式中转义句点,因此斜线是多余的:^[0-9]*(.[0-9]*)?$。也可以在数字之前和之后允许空格:^\s*[0-9]*(.[0-9]*)?\s*$ 尽管可以通过在输入字符串上调用Trim 来实现相同的目的。最后,记住TryParse 是正确答案非常重要——这只是为了好玩:)
  • Ohad Schneider:非捕获组只是学究气。我们不需要组的值,因此没有必要捕获它。
  • Ohad Schneider:至于句号,如果你只想匹配句号,你确实需要转义它。如果不转义,它会匹配任何字符,这不是我们想要的。例如,您建议的模式将匹配 123X456。
  • 糟糕,我完全忘记了句点是任何字符的通配符(\n 除外)。我的 regex-foo 确实生锈了……
  • 它将与 0 一起使用,而对于双精度值则无效。它应该是 0.0
【解决方案2】:

我敦促您使用Double.TryParse() 方法而不是正则表达式验证。使用TryParse() 让您的应用程序在文化方面更加通用。当当前文化发生变化时,TryParse() 将毫无问题地解析。 TryParse() 方法也被认为没有错误,因为它们已经过 .net 社区的测试。

但如果是正则表达式,您应该更改验证表达式,因此它可能与新文化无关。

你可以这样重写代码:

private bool IsValidInput(string p)
{
    switch (this.Type)
    {
        case NumericTextBoxType.Float:
            double doubleResult;
            return double.TryParse(p, out doubleResult);
        case NumericTextBoxType.Integer:                    
        default:
            int intResult;
            return int.TryParse(p, out intResult);
    }
}

您甚至可以添加自己的扩展方法,使解析部分更加优雅。

public static double? TryParseInt(this string source)
{
    double result;
    return double.TryParse(source, out result) ? result : (double?)null;
}

// usage
bool ok = source.TryParseInt().HasValue;

【讨论】:

  • 您的选择,但稍微短一点:private bool IsValid(string p) => this.IsFloatingPoint ? double.TryParse(p, out var d) : int.TryParse(p, out var i);
【解决方案3】:

查看您可以在 double、float 和 int 上找到的 TryParse 静态方法。

如果可以解析字符串(通过Parse 方法),则返回true。

【讨论】:

    【解决方案4】:

    我尝试了上面批准的解决方案,发现如果用户只输入一个点就会失败 @"^[0-9]*(?:\.[0-9]*)?$".

    所以,我修改为:

    @"^[0-9]*(?:\.[0-9]+)?$"
    

    【讨论】:

    • 真棒的答案,你拯救了我的一天
    【解决方案5】:

    [-+]?\d+(.\d+)?

    最简单的浮点正则表达式。它与案例“123”不匹配。或“.123”。

    另外,你应该看看上下文文化:

    CultureInfo ci = CultureInfo.CurrentCulture;
    var decimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
    var floatRegex = string.Format(@"[-+]?\d+({0}\d+)?", decimalSeparator);
    

    【讨论】:

    • 你需要像这样转义.\.
    【解决方案6】:

    这是我通过混合@Andrew Cooper 和@Ramesh 的回复得出的代码。添加了字典代码,因此任何想测试代码的人都可以轻松地运行尽可能多的测试用例。

    //greater than or equal to zero floating point numbers
    Regex floating = new Regex(@"^[0-9]*(?:\.[0-9]+)?$");
            Dictionary<string, bool> test_cases = new Dictionary<string, bool>();
            test_cases.Add("a", floating.IsMatch("a"));
            test_cases.Add("a.3", floating.IsMatch("a.3"));
            test_cases.Add("0", floating.IsMatch("0"));
            test_cases.Add("-0", floating.IsMatch("-0"));
            test_cases.Add("-1", floating.IsMatch("-1"));
            test_cases.Add("0.1", floating.IsMatch("0.1"));
            test_cases.Add("0.ab", floating.IsMatch("0.ab"));
    
            test_cases.Add("12", floating.IsMatch("12"));
            test_cases.Add(".3", floating.IsMatch(".3"));
            test_cases.Add("12.3", floating.IsMatch("12.3"));
            test_cases.Add("12.3.4", floating.IsMatch("12.3.4"));
            test_cases.Add(".", floating.IsMatch("."));
    
            test_cases.Add("0.3", floating.IsMatch("0.3"));
            test_cases.Add("12.31252563", floating.IsMatch("12.31252563"));
            test_cases.Add("-12.31252563", floating.IsMatch("-12.31252563"));
    
            foreach (KeyValuePair<string, bool> pair in test_cases)
            {
                Console.WriteLine(pair.Key.ToString() + "  -  " + pair.Value);
            }
    

    【讨论】:

      猜你喜欢
      • 2013-06-22
      • 1970-01-01
      • 2015-07-14
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      相关资源
      最近更新 更多