C# Programming

Эффективное извлечение чисел из строк в C#

Spread the love

Проверка того, представляет ли строка число, является частой задачей в разработке на C#. В этой статье рассматриваются несколько эффективных подходов, сравниваются их сильные и слабые стороны, чтобы помочь вам выбрать наилучший метод для ваших конкретных нужд.

Содержание

Использование регулярных выражений (Regex.IsMatch())

Регулярные выражения предлагают гибкое и мощное решение для проверки соответствия шаблонов строк. Метод Regex.IsMatch() позволяет определить шаблон для сопоставления с вашей входной строкой. Этот подход обычно эффективен и обрабатывает широкий спектр числовых форматов.


using System;
using System.Text.RegularExpressions;

public class StringNumberValidator
{
    public static bool IsNumber(string str)
    {
        // Шаблон для сопоставления целых чисел, чисел с плавающей точкой (включая отрицательные значения)
        return Regex.IsMatch(str, @"^-?d+(.d+)?$"); 
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(IsNumber("123"));     // True
        Console.WriteLine(IsNumber("123.45"));  // True
        Console.WriteLine(IsNumber("-123"));    // True
        Console.WriteLine(IsNumber("-123.45")); // True
        Console.WriteLine(IsNumber("123a"));    // False
        Console.WriteLine(IsNumber(""));        // False
    }
}

Вы можете изменить регулярное выражение для учета конкретных числовых форматов (например, только целые числа, числа с ограниченным количеством десятичных знаков). Это делает его очень адаптируемым к различным требованиям.

Использование методов TryParse()

Методы TryParse() (например, int.TryParse(), double.TryParse(), decimal.TryParse()) пытаются разобрать строку в числовой тип. Они возвращают true, если успешны, и false в противном случае. Это простой и часто эффективный подход, особенно когда вы знаете ожидаемый числовой тип.


using System;

public class StringNumberValidator
{
    public static bool IsInteger(string str)
    {
        int number;
        return int.TryParse(str, out number);
    }

    public static bool IsDouble(string str)
    {
        double number;
        return double.TryParse(str, out number);
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(IsInteger("123"));     // True
        Console.WriteLine(IsDouble("123.45"));  // True
        Console.WriteLine(IsInteger("-123"));    // True
        Console.WriteLine(IsInteger("123a"));    // False
        Console.WriteLine(IsInteger(""));        // False
    }
}

Выберите соответствующий метод TryParse() в зависимости от ожидаемого числового типа вашей входной строки.

Использование LINQ (Enumerable.All())

Enumerable.All() из LINQ предоставляет краткий способ проверить, удовлетворяют ли все символы в строке определенному условию. Однако этот подход ограничен положительными целыми числами без десятичных знаков или знаков минус.


using System;
using System.Linq;

public class StringNumberValidator
{
    public static bool IsPositiveInteger(string str)
    {
        return !string.IsNullOrEmpty(str) && str.All(char.IsDigit);
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(IsPositiveInteger("123"));   // True
        Console.WriteLine(IsPositiveInteger("123.45")); // False
        Console.WriteLine(IsPositiveInteger("-123"));  // False
        Console.WriteLine(IsPositiveInteger(""));      // False
    }
}

Этот метод прост и эффективен в своих ограниченных рамках, но ему не хватает универсальности других подходов.

Посимвольная проверка вручную (цикл foreach)

Вручной подход обеспечивает наибольший контроль, но обычно менее эффективен и более подвержен ошибкам. Вы будете проходить по строке, проверяя каждый символ, чтобы убедиться, что это цифра, десятичная точка или знак минус (если разрешено) в правильном положении.


using System;

public class StringNumberValidator
{
    public static bool IsNumberManual(string str)
    {
        if (string.IsNullOrEmpty(str)) return false;

        bool hasDecimal = false;
        bool hasSign = false;

        foreach (char c in str)
        {
            if (c == '-' && !hasSign && str.IndexOf(c) == 0)
            {
                hasSign = true;
                continue;
            }
            if (c == '.')
            {
                if (hasDecimal) return false;
                hasDecimal = true;
                continue;
            }
            if (!char.IsDigit(c)) return false;
        }
        return true;
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(IsNumberManual("123"));     // True
        Console.WriteLine(IsNumberManual("123.45"));  // True
        Console.WriteLine(IsNumberManual("-123"));    // True
        Console.WriteLine(IsNumberManual("-123.45")); // True
        Console.WriteLine(IsNumberManual("123a"));    // False
        Console.WriteLine(IsNumberManual(""));        // False
        Console.WriteLine(IsNumberManual("--123"));   //False
        Console.WriteLine(IsNumberManual("12.3.4"));  //False
    }
}

Хотя это обеспечивает максимальный контроль, обычно рекомендуется использовать более краткие и эффективные методы, описанные ранее, если у вас нет очень специфических требований к проверке.

В заключение, оптимальный подход зависит от ваших потребностей. Regex.IsMatch() предлагает надежное и гибкое решение для большинства сценариев, а TryParse() эффективен для простой проверки целых или чисел с плавающей точкой. Подходы LINQ и ручной цикл используются реже из-за их ограничений.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *