Como posso validar uma string para permitir apenas caracteres alfanuméricos nela?

117

Como posso validar uma string usando Expressões regulares para permitir apenas caracteres alfanuméricos nela?

(Também não quero permitir espaços).

mrblah
fonte

Respostas:

181

Use a seguinte expressão:

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

ie:

using System.Text.RegularExpressions;

Regex r = new Regex("^[a-zA-Z0-9]*$");
if (r.IsMatch(SomeString)) {
  ...
}
cletus
fonte
Que tal em javascript, a mesma coisa que eu acho?
mrblah
4
Se você limpar nomes de banco de dados ou algo interno como esse, não se importará se ele não for executado em um país de língua inglesa.
Ognyan Dimitrov
15
Eu detesto expressões regulares. Eu sei que nunca vou me lembrar da sintaxe. Mesmo se eu estudar, chegará um tempo em que tudo será esquecido novamente.
Sentinela de
1
@Phil. Talvez, mas até lá estarei delegando para alguém que conhece expressões regulares ;-)
Sentinel
3
Já foi dito: "se você resolver um problema usando expressões regulares, terá dois problemas".
O. Jones de
205

No .NET 4.0, você pode usar LINQ:

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

yourText.Allinterromperá a execução e retornará falseos char.IsLetterOrDigitrelatórios da primeira vez , falsepois o contrato de Allnão pode ser cumprido nessa ocasião .

Nota! esta resposta não verifica estritamente alfanuméricos (que normalmente é AZ, az e 0-9). Esta resposta permite personagens locais como åäö.

Atualização 29/01/2018

A sintaxe acima só funciona quando você usa um único método que tem um único argumento do tipo correto (neste caso char).

Para usar várias condições, você precisa escrever assim:

if (yourText.All(x => char.IsLetterOrDigit(x) || char.IsWhiteSpace(x)))
{
}
jgauffin
fonte
1
Eu ficaria surpreso se não fosse muito mais rápido. Nenhum regex para ser compilado ou avaliado, apenas uma comparação simples.
jgauffin
3
Agora, isso é simplesmente lindo, puro e simples.
Sentinela de
3
Isso não vai falhar se você quiser ter certeza de que seu Texto é definitivamente alfanumérico? Podem ser todos os dígitos ou todos os alfabetos, mas ainda assim satisfazem essa condição.
itsbalur
2
@itsbalur: Sim, mas essa não era a questão.
jgauffin
2
Acho que essa resposta está simplesmente errada, supondo que o conjunto alfanumérico seja AZ, az e 0-9, porque isso cobre toda a gama de letras e dígitos Unicode, incluindo caracteres não latinos também. Por exemplo, char.IsLetterOrDigit('ก')retornará true. csharppad.com/gist/f96a6062f9f8f4e974f222ce313df8ca
tia
34

Você poderia fazer isso facilmente com uma função de extensão em vez de um regex ...

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 comentário :) ...

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
fonte
2
Pode ser uma questão de gosto, mas eu expressaria o loop como "foreach (char c in str) {...}". Se uma string vazia deve ser considerada OK depende do aplicativo, então eu retiraria isso. Eu também não preencheria 6 linhas vazias em uma rotina tão trivial, mas acho que é o estilo C # / Java / C ++ - os programadores parecem ser pagos pelo espaço da tela. De qualquer forma, esta é a direção certa, então +1.
Svante
3
Acho que gostaríamos de usar IsDigit nesta situação, em vez de IsNumber - IsNumber retornará true para dígitos ou para coisas que se parecem com números (frações, algarismos romanos, etc .; consulte msdn.microsoft.com/ en-us / library / yk2b3t2y.aspx ). Dado isso, e se alguém estiver se sentindo particularmente mal, pode compactar o conteúdo de IsAlphaNum ainda mais: return string.IsNullOrEmpty (str)? falso: str.ToCharArray (). All (Char.IsLetterOrDigit);
pilha
4
Observe que Char.IsLetter será avaliado como verdadeiro para "letras" diferentes de a-zA-Z. Por exemplo, あ japonês, 的 chinês, 한 coreano etc. são considerados "letras" Unicode. Se essa for sua intenção, tudo bem, mas a julgar pelas várias expressões regex nas outras respostas, provavelmente não é o que a maioria considera alfa [numérico].
Dono de
No meu caso, além de IsLetter e IsNumber, eu também precisava do IsWhiteSpace, então o adicionei ao seu código e funcionou perfeitamente!
Ben Junior
use char.IsLetterOrDigitIsLetter + IsNumber
nick_n_a
17

Embora eu ache que a solução baseada em regex é provavelmente o caminho que eu escolheria, ficaria tentado a encapsular isso em um 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;
    }
}

Agora, quando você precisa de uma string validada, pode fazer com que a assinatura do método exija uma AlphaNumericString e saiba que, se obtiver uma, ela é válida (exceto nulos). Se alguém tentar passar uma string não validada, um erro do compilador será gerado.

Você pode obter mais elaborado e implementar todos os operadores de igualdade, ou uma conversão explícita para AlphaNumericString de uma string simples, se você se importar.

Kyoryu
fonte
Nunca vi essa abordagem, mas gosto da clareza de intenção e de sua justificativa. +1.
Cory House
1
Isso é novo para mim. Estou tentando entender a static public implicit operator stringparte
Hassan Gulzar
8

Eu precisava verificar AZ, az, 0-9; sem uma regex (mesmo que o OP solicite a regex).

Combinando várias respostas e comentários aqui e discussão de https://stackoverflow.com/a/9975693/292060 , isso testa a letra ou o dígito, evitando letras de outros idiomas e evitando outros números, como caracteres fracionários.

if (!String.IsNullOrEmpty(testString)
    && testString.All(c => Char.IsLetterOrDigit(c) && (c < 128)))
{
    // Alphanumeric.
}
Bom olho
fonte
4

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

Use ^[a-zA-Z0-9]+$para impedir o sublinhado.

Observe que ambos exigem que a string não esteja vazia. Usar em *vez de +permite strings vazias.

Peter Boughton
fonte
como eu poderia mudar seu ^ \ w + $ para permitir também o caractere traço "-"?
Neal Davis
@NealDavis^[\w-]+$
Zachafer
2

Para verificar se a string é uma combinação de letras e dígitos, você pode reescrever a resposta @jgauffin da seguinte maneira usando .NET 4.0 e LINQ:

if(!string.IsNullOrWhiteSpace(yourText) && 
yourText.Any(char.IsLetter) && yourText.Any(char.IsDigit))
{
   // do something here
}
Thabiso Mofokeng
fonte
Isso reconhecerá incorretamente a string contendo outros caracteres junto com alfanuméricos ...
nsimeonov
1

Mesma resposta que aqui .

Se você quiser uma A-z 0-9verificação ASCII sem regex , não poderá usar, char.IsLetterOrDigit()pois isso inclui outros caracteres Unicode.

O que você pode fazer é verificar os intervalos de código de caracteres.

  • 48 -> 57 são numéricos
  • 65 -> 90 são letras maiúsculas
  • 97 -> 122 são letras minúsculas

O que segue é um pouco mais detalhado, mas é para facilitar o entendimento e não para definir o código.

    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
fonte
0

Com base na resposta de cletus, você pode criar uma nova extensão.

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
fonte
-8

Aconselho não depender de código pronto e embutido no framework .NET, tente trazer uma nova solução .. é isso que eu faço ..

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
fonte
2
Você poderia adicionar alguma explicação ao seu código, apenas despejar o código é geralmente desaprovado aqui
Draken
Eles também pediram expressões regulares, mas não são expressões regulares
Draken
Obrigado pelo comentário e observação ... como aconselhei, tenho minha própria abordagem para escrever código.
Mahdi Al Aradi
5
Seu comentário sobre não depender de código pré-compilado em .Net faz pouco sentido, certamente se você não deveria confiar no código pré-compilado, você não deveria usar o char.IsNumber()método, já que é um código pré-compilado .
Draken
4
Este código é um ótimo exemplo de por que reinventá-lo sozinho é uma ideia tão ruim - ele não faz o que você queria fazer! (A string "@ 1a" retornará verdadeiro incorretamente, a string "a" retornará falso)
Flexo