¿Cómo puedo validar una cadena para permitir solo caracteres alfanuméricos en ella?

117

¿Cómo puedo validar una cadena usando expresiones regulares para permitir solo caracteres alfanuméricos en ella?

(Tampoco quiero permitir espacios).

mrblah
fuente

Respuestas:

181

Utilice la siguiente expresión:

^[a-zA-Z0-9]*$

es decir:

using System.Text.RegularExpressions;

Regex r = new Regex("^[a-zA-Z0-9]*$");
if (r.IsMatch(SomeString)) {
  ...
}
cletus
fuente
¿Qué tal en javascript, lo mismo supongo?
mrblah
4
Si desinfecta los nombres de la base de datos o algo interno como ese, no le importará si no se ejecuta en un país de habla inglesa.
Ognyan Dimitrov
15
Detesto las expresiones regulares. Sé que nunca recordaré la sintaxis. Incluso si lo estudio, pronto llegará un momento en que todo se olvidará de nuevo.
Sentinel
1
@Phil. Tal vez, pero para entonces delegaré en alguien que sepa las expresiones regulares ;-)
Sentinel
3
Se ha dicho, "si resuelves un problema usando expresiones regulares, entonces tienes dos problemas".
O. Jones
205

En .NET 4.0 puede usar LINQ:

if (yourText.All(char.IsLetterOrDigit))
{
    //just letters and digits.
}

yourText.Alldejará de ejecutarse y devolverá falselos char.IsLetterOrDigitinformes por primera vez falseya que el contrato de Allno se puede cumplir en ese momento.

¡Nota! esta respuesta no comprueba estrictamente los caracteres alfanuméricos (que normalmente son AZ, az y 0-9). Esta respuesta permite personajes locales como åäö.

Actualización 2018-01-29

La sintaxis anterior solo funciona cuando usa un solo método que tiene un solo argumento del tipo correcto (en este caso char).

Para usar múltiples condiciones, debe escribir así:

if (yourText.All(x => char.IsLetterOrDigit(x) || char.IsWhiteSpace(x)))
{
}
jgauffin
fuente
1
Me sorprendería que no fuera mucho más rápido. No hay expresiones regulares para compilar o evaluar, solo una simple comparación.
jgauffin
3
Eso es simplemente hermoso, simple y llanamente.
Sentinel
3
¿No fallará esto si quiere asegurarse de que su texto sea definitivamente alfanumérico? Puede ser de todos los dígitos o todos los alfabetos, pero aún así cumple esta condición.
itsbalur
2
@itsbalur: Sí, pero esa no era la cuestión.
jgauffin
2
Creo que esta respuesta es simplemente incorrecta, asumiendo que el conjunto alfanumérico es AZ, az y 0-9 porque cubre todo el rango de letras y dígitos Unicode, que también incluye caracteres no latinos. Por ejemplo, char.IsLetterOrDigit('ก')volverá true. csharppad.com/gist/f96a6062f9f8f4e974f222ce313df8ca
tia
34

Puede hacerlo fácilmente con una función de extensión en lugar de una expresión regular ...

public static bool IsAlphaNum(this string str)
{
    if (string.IsNullOrEmpty(str))
        return false;

    for (int i = 0; i < str.Length; i++)
    {
        if (!(char.IsLetter(str[i])) && (!(char.IsNumber(str[i]))))
            return false;
    }

    return true;
}

Por comentario :) ...

public static bool IsAlphaNum(this string str)
{
    if (string.IsNullOrEmpty(str))
        return false;

    return (str.ToCharArray().All(c => Char.IsLetter(c) || Char.IsNumber(c)));
}
JP Alioto
fuente
2
Puede ser una cuestión de gustos, pero expresaría el bucle como "foreach (char c in str) {...}". El hecho de que una cadena vacía se considere correcta depende de la aplicación, por lo que eliminaría esto. Tampoco agregaría 6 líneas vacías a una rutina tan trivial, pero supongo que ese es el estilo C # / Java / C ++: parece que los codificadores se pagan con el espacio en pantalla. De todos modos, esta es la dirección correcta, así que +1.
Svante
3
Creo que nos gustaría usar IsDigit en esta situación, en lugar de IsNumber: IsNumber devolverá verdadero para dígitos o para cosas que parecen números (fracciones, números romanos, etc .; consulte msdn.microsoft.com/ en-us / library / yk2b3t2y.aspx ). Dado eso, y si uno se sintiera particularmente malvado, podría comprimir el contenido de IsAlphaNum aún más: return string.IsNullOrEmpty (str)? falso: str.ToCharArray (). All (Char.IsLetterOrDigit);
pila
4
Tenga en cuenta que Char.IsLetter se evaluará como verdadero para "letras" distintas de a-zA-Z. Por ejemplo, japonés あ, chino 的, coreano 한, etc. se consideran "letras" Unicode. Si esta es su intención, entonces está bien, pero a juzgar por las diversas expresiones regulares en las otras respuestas, esto probablemente no sea lo que la mayoría considera alfanumérico.
Dono
En mi caso, además de IsLetter e IsNumber, también necesitaba IsWhiteSpace, así que lo agregué a su código y ¡funcionó perfectamente!
Ben Junior
use char.IsLetterOrDigiten su lugar IsLetter + IsNumber
nick_n_a
17

Si bien creo que la solución basada en expresiones regulares es probablemente la forma en que iría, estaría tentado a encapsular esto en un tipo.

public class AlphaNumericString
{
    public AlphaNumericString(string s)
    {
        Regex r = new Regex("^[a-zA-Z0-9]*$");
        if (r.IsMatch(s))
        {
            value = s;                
        }
        else
        {
            throw new ArgumentException("Only alphanumeric characters may be used");
        }
    }

    private string value;
    static public implicit operator string(AlphaNumericString s)
    {
        return s.value;
    }
}

Ahora, cuando necesite una cadena validada, puede hacer que la firma del método requiera una AlphaNumericString, y saber que si obtiene una, es válida (aparte de los nulos). Si alguien intenta pasar una cadena no validada, generará un error del compilador.

Puede ser más elegante e implementar todos los operadores de igualdad, o una conversión explícita a AlphaNumericString desde una cadena simple, si le importa.

Kyoryu
fuente
Nunca he visto este enfoque, pero me gusta la claridad de intención y su justificación. +1.
Cory House
1
Esto es nuevo para mi. Estoy tratando de entender la static public implicit operator stringparte
Hassan Gulzar
8

Necesitaba buscar AZ, az, 0-9; sin una expresión regular (aunque el OP solicita una expresión regular).

Combinando varias respuestas y comentarios aquí, y la discusión de https://stackoverflow.com/a/9975693/292060 , esto prueba la letra o el dígito, evitando letras de otros idiomas y evitando otros números como caracteres de fracción.

if (!String.IsNullOrEmpty(testString)
    && testString.All(c => Char.IsLetterOrDigit(c) && (c < 128)))
{
    // Alphanumeric.
}
buen ojo
fuente
4

^\w+$ permitirá a-zA-Z0-9_

Utilizar ^[a-zA-Z0-9]+$ para no permitir el subrayado.

Tenga en cuenta que ambos requieren que la cadena no esté vacía. Usar en *lugar de +permite cadenas vacías.

Peter Boughton
fuente
¿Cómo podría cambiar su ^ \ w + $ para permitir también el carácter de guión "-"?
Neal Davis
@NealDavis^[\w-]+$
Zachafer
2

Para verificar si la cadena es una combinación de letras y dígitos, puede reescribir la respuesta de @jgauffin de la siguiente manera usando .NET 4.0 y LINQ:

if(!string.IsNullOrWhiteSpace(yourText) && 
yourText.Any(char.IsLetter) && yourText.Any(char.IsDigit))
{
   // do something here
}
Thabiso Mofokeng
fuente
Esto reconocerá incorrectamente la cadena que contiene otros caracteres junto con alfanuméricos ...
nsimeonov
1

Misma respuesta que aquí .

Si desea una A-z 0-9verificación ASCII que no sea de expresiones regulares , no puede usarla, char.IsLetterOrDigit()ya que incluye otros caracteres Unicode.

Lo que puede hacer es verificar los rangos de códigos de caracteres.

  • 48 -> 57 son números
  • 65 -> 90 son letras mayúsculas
  • 97 -> 122 son letras minúsculas

Lo siguiente es un poco más detallado, pero es para facilitar la comprensión más que para el código de golf.

    public static bool IsAsciiAlphaNumeric(this string str)
    {
        if (string.IsNullOrEmpty(str))
        {
            return false;
        }

        for (int i = 0; i < str.Length; i++)
        {
            if (str[i] < 48) // Numeric are 48 -> 57
            {
                return false;
            }

            if (str[i] > 57 && str[i] < 65) // Capitals are 65 -> 90
            {
                return false;
            }

            if (str[i] > 90 && str[i] < 97) // Lowers are 97 -> 122
            {
                return false;
            }

            if (str[i] > 122)
            {
                return false;
            }
        }

        return true;
    }
Douglas Gaskell
fuente
0

Según la respuesta de cletus, puede crear una nueva extensión.

public static class StringExtensions
{        
    public static bool IsAlphaNumeric(this string str)
    {
        if (string.IsNullOrEmpty(str))
            return false;

        Regex r = new Regex("^[a-zA-Z0-9]*$");
        return r.IsMatch(str);
    }
}
Alexa Adrian
fuente
-8

Aconsejo no depender del código prefabricado e integrado en .NET framework, intente traer una nueva solución ... esto es lo que hago ...

public  bool isAlphaNumeric(string N)
{
    bool YesNumeric = false;
    bool YesAlpha = false;
    bool BothStatus = false;


    for (int i = 0; i < N.Length; i++)
    {
        if (char.IsLetter(N[i]) )
            YesAlpha=true;

        if (char.IsNumber(N[i]))
            YesNumeric = true;
    }

    if (YesAlpha==true && YesNumeric==true)
    {
        BothStatus = true;
    }
    else
    {
        BothStatus = false;
    }
    return BothStatus;
}
Mahdi Al Aradi
fuente
2
¿Podría por favor agregar alguna explicación a su código? Solo el volcado de código está generalmente mal visto aquí
Draken
También pidieron expresiones regulares, estas no son expresiones regulares
Draken
Gracias por el comentario y la observación ... como le dije, tengo mi propio enfoque para escribir código.
Mahdi Al Aradi
5
Su comentario sobre no confiar en el código preconstruido en .Net tiene poco sentido, seguramente si no debe confiar en el código precompilado, ¿no debería usar el char.IsNumber()método ya que es un código preconstruido?
Draken
4
Este código es un gran ejemplo de por qué reinventarlo usted mismo es una mala idea: ¡en realidad no hace lo que quería hacer! (La cadena "@ 1a" devolverá verdadero incorrectamente, la cadena "a" devolverá falso)
Flexo