Jak mogę zweryfikować ciąg, aby zezwalał tylko na znaki alfanumeryczne?


117

Jak mogę zweryfikować ciąg przy użyciu wyrażeń regularnych, aby zezwalać tylko na znaki alfanumeryczne?

(Nie chcę też dopuszczać żadnych spacji).

Odpowiedzi:


181

Użyj następującego wyrażenia:

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

to znaczy:

using System.Text.RegularExpressions;

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

Co powiesz na javascript, myślę, że to samo?
mrblah

4
Jeśli wyczyścisz nazwy baz danych lub coś w tym rodzaju, nie będziesz się przejmować, jeśli nie będą działać w kraju anglojęzycznym.
Ognyan Dimitrov

15
Nie znoszę wyrażeń regularnych. Wiem, że nigdy nie zapamiętam składni. Nawet jeśli go przestudiuję, wkrótce nadejdzie czas, kiedy znowu o tym zapomnę.
Sentinel

1
@Phil. Może, ale do tego czasu będę delegować kogoś, kto zna wyrażenia regularne ;-)
Sentinel

3
Mówi się, że „jeśli rozwiązujesz problem za pomocą wyrażeń regularnych, masz dwa problemy”.
O. Jones,

205

W .NET 4.0 możesz użyć LINQ:

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

yourText.Allprzestanie wykonywać i zwróci falsepierwsze char.IsLetterOrDigitraporty, falseponieważ umowa Allnie może być wtedy wykonana .

Uwaga! ta odpowiedź nie sprawdza ściśle znaków alfanumerycznych (zwykle są to AZ, az i 0-9). Ta odpowiedź zezwala na lokalne znaki, takie jak åäö.

Aktualizacja 2018-01-29

Powyższa składnia działa tylko wtedy, gdy używasz pojedynczej metody, która ma pojedynczy argument prawidłowego typu (w tym przypadku char).

Aby użyć wielu warunków, musisz napisać w ten sposób:

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

1
Zdziwiłbym się, gdyby nie było dużo szybciej. Brak wyrażenia regularnego do kompilacji lub oceny, tylko proste porównanie.
jgauffin

3
To jest po prostu piękne, proste i proste.
Sentinel

3
Czy to nie zawiedzie, jeśli chcesz mieć pewność, że Twój tekst jest zdecydowanie alfanumeryczny? Mogą to być wszystkie cyfry lub wszystkie alfabety, ale nadal spełniają ten warunek.
itsbalur

2
@itsbalur: Tak, ale to nie było pytanie.
jgauffin

2
Myślę, że ta odpowiedź jest po prostu błędna, zakładając, że zestaw alfanumeryczny to AZ, az i 0-9, ponieważ obejmuje to cały zakres liter i cyfr Unicode, w tym również znaki spoza alfabetu łacińskiego. Na przykład char.IsLetterOrDigit('ก')zwróci true. csharppad.com/gist/f96a6062f9f8f4e974f222ce313df8ca
tia

34

Możesz to łatwo zrobić za pomocą funkcji rozszerzającej zamiast wyrażenia regularnego ...

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

Za komentarz :) ...

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
Może to kwestia gustu, ale określiłbym pętlę jako „foreach (char c in str) {...}”. To, czy pusty ciąg ma być uznany za OK, zależy od aplikacji, więc chciałbym to usunąć. Nie dopełniłbym też 6 pustych wierszy w tak trywialną procedurę, ale myślę, że to styl C # / Java / C ++ - wydaje się, że programiści są opłacani przez nieruchomości ekranowe. W każdym razie to właściwy kierunek, więc +1.
Svante

3
Myślę, że w tej sytuacji chcielibyśmy użyć IsDigit zamiast IsNumber - IsNumber zwróci wartość true dla cyfr lub rzeczy, które wyglądają jak liczby (ułamki, cyfry rzymskie itp .; patrz msdn.microsoft.com/ en-us / library / yk2b3t2y.aspx ). Biorąc to pod uwagę i jeśli ktoś czuł się szczególnie zły, można by jeszcze bardziej skompresować zawartość IsAlphaNum: return string.IsNullOrEmpty (str)? false: str.ToCharArray (). All (Char.IsLetterOrDigit);
stos

4
Zauważ, że Char.IsLetter przyjmie wartość true dla „liter” innych niż a-zA-Z. Na przykład japońskie あ, chińskie 的, koreańskie 한 itd. Są uważane za „litery” Unicode. Jeśli taki jest Twój zamiar, to dobrze, ale sądząc po różnych wyrażeniach regularnych w innych odpowiedziach, prawdopodobnie nie jest to to, co najczęściej uważa się za alfa [numeryczne].
Dono

W moim przypadku oprócz IsLetter i IsNumber potrzebowałem również IsWhiteSpace, więc dodałem go do twojego kodu i działało idealnie!
Ben Junior

użyj char.IsLetterOrDigitzamiast tego IsLetter + IsNumber
nick_n_a

17

Chociaż myślę, że rozwiązanie oparte na wyrażeniach regularnych jest prawdopodobnie drogą, którą bym poszedł, miałbym pokusę, aby zawrzeć to w typie.

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

Teraz, gdy potrzebujesz zweryfikowanego ciągu, możesz mieć podpis metody, aby wymagał AlphaNumericString i wiedzieć, że jeśli go otrzymasz, jest prawidłowy (oprócz wartości null). Jeśli ktoś spróbuje przekazać niezatwierdzony ciąg, wygeneruje błąd kompilatora.

Możesz uzyskać bardziej wyszukane i zaimplementować wszystkie operatory równości lub jawne rzutowanie na AlphaNumericString ze zwykłego łańcucha, jeśli ci zależy.


Nigdy nie widziałem takiego podejścia, ale podoba mi się jasność intencji i twoje uzasadnienie. +1.
Cory House,

1
To jest dla mnie nowość. Próbuję zrozumieć static public implicit operator stringczęść
Hassan Gulzar

8

Musiałem sprawdzić AZ, az, 0-9; bez wyrażenia regularnego (nawet jeśli OP pyta o wyrażenie regularne).

Łącząc tutaj różne odpowiedzi i komentarze oraz dyskusję z https://stackoverflow.com/a/9975693/292060 , ten test sprawdza litery lub cyfry, unikając liter w innych językach i unikając innych liczb, takich jak znaki ułamkowe.

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

4

^\w+$ pozwoli a-zA-Z0-9_

Służy ^[a-zA-Z0-9]+$do blokowania podkreślenia.

Zauważ, że oba wymagają, aby ciąg nie był pusty. Używanie *zamiast +zezwala na puste ciągi.


jak mogę zmienić twoje ^ \ w + $, aby zezwolić także na znak myślnika „-”?
Neal Davis

@NealDavis^[\w-]+$
Zachafer

2

Aby sprawdzić, czy ciąg jest kombinacją liter i cyfr, możesz ponownie napisać odpowiedź @jgauffin w następujący sposób, używając .NET 4.0 i LINQ:

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

To niepoprawnie rozpozna ciąg zawierający inne znaki wraz z alfanumerycznym ...
nsimeonov

1

Ta sama odpowiedź jak tutaj .

Jeśli chcesz A-z 0-9sprawdzić ASCII inne niż regex , nie możesz użyć, char.IsLetterOrDigit()ponieważ obejmuje to inne znaki Unicode.

Możesz sprawdzić zakresy kodów znaków.

  • 48 -> 57 to cyfry
  • 65 -> 90 to wielkie litery
  • 97 -> 122 to małe litery

Poniższy tekst jest nieco bardziej szczegółowy, ale służy raczej do zrozumienia niż do kodowania golfa.

    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

Na podstawie odpowiedzi Cletusa możesz utworzyć nowe rozszerzenie.

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

Radzę nie polegać na gotowym i wbudowanym kodzie w .NET frameworku, spróbować stworzyć nowe rozwiązanie .. to właśnie robię ..

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
Czy mógłbyś dodać jakieś wyjaśnienie do swojego kodu, po prostu wrzucanie kodu jest tutaj generalnie źle
widziane

Poprosili też o wyrażenia regularne, to nie są wyrażenia regularne
Draken

Dziękuję za komentarz i obserwację ... jak radziłem, mam własne podejście do pisania kodu.
Mahdi Al Aradi

5
Twój komentarz o tym, że nie polegasz na kodzie przed kompilacją w .Net, nie ma sensu, z pewnością jeśli nie powinieneś polegać na kodzie przed kompilacją, nie powinieneś używać char.IsNumber()metody, ponieważ jest to kod wstępnie zbudowany?
Draken

4
Ten kod jest doskonałym przykładem tego, dlaczego samodzielne wymyślanie go na nowo to taki zły pomysł - w rzeczywistości nie robi tego, co chciałeś! (Ciąg „@ 1a” zwróci wartość prawda nieprawidłowo, ciąg „a” zwróci fałsz)
Flexo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.