Come posso convalidare una stringa per consentire solo caratteri alfanumerici in essa?


117

Come posso convalidare una stringa utilizzando espressioni regolari per consentire solo caratteri alfanumerici in essa?

(Non voglio nemmeno consentire spazi).

Risposte:


181

Usa la seguente espressione:

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

vale a dire:

using System.Text.RegularExpressions;

Regex r = new Regex("^[a-zA-Z0-9]*$");
if (r.IsMatch(SomeString)) {
  ...
}

Che ne dici di javascript, la stessa cosa immagino?
mrblah,

4
Se disinfetti i nomi dei database o qualcosa di interno del genere non ti interesserà se non viene eseguito in un paese di lingua inglese.
Ognyan Dimitrov

15
Detesto le espressioni regolari. So che non ricorderò mai la sintassi. Anche se lo studio, presto arriverà un momento in cui sarà di nuovo tutto dimenticato.
Sentinel

1
@Phil. Forse, ma per allora delegherò a qualcuno che conosce le espressioni regolari ;-)
Sentinel

3
È stato detto: "se risolvi un problema utilizzando espressioni regolari, hai due problemi".
O. Jones,

205

In .NET 4.0 puoi usare LINQ:

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

yourText.Allinterromperà l'esecuzione e restituirà falsei char.IsLetterOrDigitrapporti per la prima volta falsepoiché il contratto di Allnon può essere adempiuto in quel momento.

Nota! questa risposta non controlla rigorosamente i caratteri alfanumerici (che tipicamente sono AZ, az e 0-9). Questa risposta consente caratteri locali come åäö.

Aggiornamento 2018-01-29

La sintassi precedente funziona solo quando si utilizza un singolo metodo con un singolo argomento del tipo corretto (in questo caso char ).

Per utilizzare più condizioni, devi scrivere in questo modo:

if (yourText.All(x => char.IsLetterOrDigit(x) || char.IsWhiteSpace(x)))
{
}

1
Sarei sorpreso se non fosse molto più veloce. Nessuna regex da compilare o valutare, solo un semplice confronto.
jgauffin

3
Questo è semplicemente bello, chiaro e semplice.
Sentinel

3
Non fallirà se vuoi assicurarti che il tuo testo sia decisamente alfanumerico? Può essere composto da tutte le cifre o da tutti gli alfabeti, ma soddisfa comunque questa condizione.
itsbalur

2
@itsbalur: Sì, ma non era questo il problema.
jgauffin

2
Penso che questa risposta sia semplicemente sbagliata, supponendo che il set alfanumerico sia AZ, az e 0-9 perché questo copre l'intera gamma di lettere e cifre Unicode, inclusi anche i caratteri non latini. Ad esempio, char.IsLetterOrDigit('ก')tornerà true. csharppad.com/gist/f96a6062f9f8f4e974f222ce313df8ca
tia

34

Potresti farlo facilmente con una funzione di estensione piuttosto che una 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;
}

Per commento :) ...

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

    return (str.ToCharArray().All(c => Char.IsLetter(c) || Char.IsNumber(c)));
}

2
Potrebbe essere una questione di gusti, ma esprimerei il ciclo come "foreach (char c in str) {...}". Se una stringa vuota deve essere considerata OK dipende dall'applicazione, quindi la eliminerei. Inoltre, non aggiungerei 6 righe vuote in una routine così banale, ma immagino che sia lo stile C # / Java / C ++: i programmatori sembrano essere pagati dallo schermo. Comunque, questa è la giusta direzione, quindi +1.
Svante

3
Penso che vorremmo utilizzare IsDigit in questa situazione, piuttosto che IsNumber: IsNumber restituirà true per le cifre o per le cose che sembrano numeri (frazioni, numeri romani, ecc .; vedere msdn.microsoft.com/ it / library / yk2b3t2y.aspx ). Detto questo, e se ci si sentisse particolarmente male, si potrebbe comprimere ulteriormente il contenuto di IsAlphaNum: return string.IsNullOrEmpty (str)? false: str.ToCharArray (). All (Char.IsLetterOrDigit);
impila il

4
Tieni presente che Char.IsLetter restituirà true per "lettere" diverse da a-zA-Z. Ad esempio, il giapponese あ, il cinese 的, il coreano 한 ecc. Sono considerati "lettere" Unicode. Se questa è la tua intenzione, allora va bene, ma a giudicare dalle varie espressioni regex nelle altre risposte, questo probabilmente non è ciò che più viene considerato alfa [numerico].
Dono

Nel mio caso, oltre a IsLetter e IsNumber avevo anche bisogno di IsWhiteSpace, quindi l'ho aggiunto al tuo codice e ha funzionato perfettamente!
Ben Junior

usa char.IsLetterOrDigitinvece IsLetter + IsNumber
nick_n_a

17

Anche se penso che la soluzione basata su regex sia probabilmente il modo in cui andrei, sarei tentato di incapsularlo in 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;
    }
}

Ora, quando hai bisogno di una stringa convalidata, puoi fare in modo che la firma del metodo richieda un AlphaNumericString e sapere che se ne ottieni uno, è valido (a parte i null). Se qualcuno tenta di passare una stringa non convalidata, genererà un errore del compilatore.

Puoi diventare più elaborato e implementare tutti gli operatori di uguaglianza o un cast esplicito a AlphaNumericString dalla semplice stringa, se ti interessa.


Non ho mai visto questo approccio, ma mi piace la chiarezza degli intenti e la tua giustificazione. +1.
Cory House,

1
Questo mi è nuovo. Sto cercando di capire la static public implicit operator stringparte
Hassan Gulzar

8

Dovevo controllare AZ, az, 0-9; senza regex (anche se l'OP richiede regex).

Mescolando qui varie risposte e commenti e discussioni da https://stackoverflow.com/a/9975693/292060 , questo verifica la lettera o la cifra, evitando lettere in altre lingue ed evitando altri numeri come i caratteri frazionari.

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

4

^\w+$ permetterà a-zA-Z0-9_

Utilizzare ^[a-zA-Z0-9]+$per non consentire il carattere di sottolineatura.

Nota che entrambi richiedono che la stringa non sia vuota. L'utilizzo *invece di +consente stringhe vuote.


come potrei cambiare il tuo ^ \ w + $ per consentire anche il trattino "-"?
Neal Davis

@NealDavis^[\w-]+$
Zachafer

2

Per verificare se la stringa è sia una combinazione di lettere che di cifre, puoi riscrivere la risposta @jgauffin come segue utilizzando .NET 4.0 e LINQ:

if(!string.IsNullOrWhiteSpace(yourText) && 
yourText.Any(char.IsLetter) && yourText.Any(char.IsDigit))
{
   // do something here
}

Questo riconoscerà erroneamente la stringa contenente altri caratteri insieme a caratteri alfanumerici ...
nsimeonov

1

Stessa risposta come qui .

Se vuoi un A-z 0-9controllo ASCII non regex , non puoi usarechar.IsLetterOrDigit() poiché include altri caratteri Unicode.

Quello che puoi fare è controllare gli intervalli di codici dei caratteri.

  • 48 -> 57 sono valori numerici
  • 65 -> 90 sono lettere maiuscole
  • 97 -> 122 sono lettere minuscole

Quanto segue è un po 'più dettagliato, ma è per facilità di comprensione piuttosto che per il golf in codice.

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

0

In base alla risposta di Cletus puoi creare una nuova estensione.

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

-8

Consiglio di non dipendere da codice già pronto e integrato in .NET framework, prova a far apparire una nuova soluzione .. questo è quello che faccio

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

2
Potresti per favore aggiungere qualche spiegazione al tuo codice, il solo dumping del codice è generalmente disapprovato qui
Draken

Inoltre hanno chiesto espressioni regolari, non si tratta di espressioni regolari
Draken

Grazie per il commento e l'osservazione .. come ho consigliato ho il mio approccio per scrivere il codice.
Mahdi Al Aradi

5
Il tuo commento sul non fare affidamento sul codice pre-compilato in .Net ha poco senso, sicuramente se non dovresti fare affidamento sul codice pre-compilato, non dovresti usare il char.IsNumber()metodo in quanto è codice pre-compilato?
Draken

4
Questo codice è un ottimo esempio del motivo per cui reinventarlo da soli è una pessima idea: in realtà non fa quello che volevi! (La stringa "@ 1a" restituirà true in modo errato, la stringa "a" restituirà false)
Flexo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.