C# Programming

Identificación Eficiente de Números en Cadenas C#

Spread the love

Validar si una cadena representa un número es una tarea frecuente en el desarrollo en C#. Este artículo explora varios enfoques eficientes, comparando sus fortalezas y debilidades para ayudarlo a elegir el mejor método para sus necesidades específicas.

Tabla de contenido

Usando expresiones regulares (Regex.IsMatch())

Las expresiones regulares ofrecen una solución flexible y potente para validar patrones de cadenas. El método Regex.IsMatch() le permite definir un patrón para comparar con su cadena de entrada. Este enfoque generalmente es eficiente y maneja una amplia gama de formatos numéricos.


using System;
using System.Text.RegularExpressions;

public class StringNumberValidator
{
    public static bool IsNumber(string str)
    {
        // Patrón para coincidir con enteros, números de punto flotante (incluidos valores negativos)
        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
    }
}

Puede ajustar la expresión regular para adaptarse a formatos numéricos específicos (por ejemplo, solo enteros, números con un número limitado de decimales). Esto lo hace altamente adaptable a varios requisitos.

Usando métodos TryParse()

Los métodos TryParse() (por ejemplo, int.TryParse(), double.TryParse(), decimal.TryParse()) intentan analizar la cadena en un tipo numérico. Devuelven true si tienen éxito y false de lo contrario. Este es un enfoque sencillo y a menudo eficiente, especialmente cuando conoce el tipo numérico esperado.


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
    }
}

Elija el método TryParse() apropiado según el tipo numérico esperado de su cadena de entrada.

Usando LINQ (Enumerable.All())

Enumerable.All() de LINQ proporciona una forma concisa de verificar si todos los caracteres de una cadena cumplen una determinada condición. Sin embargo, este enfoque se limita a enteros positivos sin puntos decimales o signos negativos.


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
    }
}

Este método es simple y eficiente para su alcance limitado, pero carece de la versatilidad de otros enfoques.

Verificación manual carácter por carácter (bucle foreach)

Un enfoque manual ofrece el mayor control, pero generalmente es menos eficiente y más propenso a errores. Iteraría a través de la cadena, verificando cada carácter para asegurarse de que sea un dígito, un punto decimal o un signo menos (si está permitido) en la posición correcta.


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
    }
}

Si bien esto proporciona el máximo control, generalmente se recomienda usar los métodos más concisos y eficientes que se describieron anteriormente a menos que tenga requisitos de validación muy específicos.

En resumen, el enfoque óptimo depende de sus necesidades. Regex.IsMatch() ofrece una solución robusta y flexible para la mayoría de los escenarios, mientras que TryParse() es eficiente para la validación simple de enteros o de punto flotante. Los enfoques LINQ y de bucle manual se prefieren con menos frecuencia debido a sus limitaciones.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *