Проверьте число с плавающей точкой, используя RegEx в C # - PullRequest
10 голосов
/ 02 февраля 2012

Я пытаюсь сделать только числовой TextBox в WPF, и у меня есть этот код для него:

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 элементов управления, но мне было интересно, почему этот не работает?

Ответы [ 6 ]

23 голосов
/ 02 февраля 2012

Попробуйте это:

@"^[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 
13 голосов
/ 02 февраля 2012

Я призываю вас использовать 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;
4 голосов
/ 02 февраля 2012

Проверьте TryParse статические методы, которые вы найдете в double, float и int.

Они возвращают true, если строка может быть проанализирована (методом Parse).

2 голосов
/ 26 мая 2013

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

Самое простое регулярное выражение для float. Если это не соответствует случаям «123.» или «.123».

Кроме того, вы должны взглянуть на контекстную культуру:

CultureInfo ci = CultureInfo.CurrentCulture;
var decimalSeparator = ci.NumberFormat.NumberDecimalSeparator;
var floatRegex = string.Format(@"[-+]?\d+({0}\d+)?", decimalSeparator);
1 голос
/ 29 мая 2013

Я попробовал решение, одобренное выше, обнаружил, что оно не будет работать, если пользователь введет только точку @"^[0-9]*(?:\.[0-9]*)?$".

Итак, я изменил его на:

@"^[0-9]*(?:\.[0-9]+)?$"
0 голосов
/ 24 мая 2016

Это код, который я придумал, смешав ответы @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);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...