Як я можу перевірити рядок, щоб дозволити в ньому лише буквено-цифрові символи?


117

Як я можу перевірити рядок за допомогою регулярних виразів, щоб дозволити в ньому лише буквено-цифрові символи?

(Я також не хочу допускати жодних пробілів).

Відповіді:


181

Використовуйте такий вираз:

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

тобто:

using System.Text.RegularExpressions;

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

Як щодо JavaScript, те саме, що я здогадуюсь?
mrblah

4
Якщо ви очистите імена баз даних або щось подібне внутрішнє, вам буде байдуже, якщо вона не працює в англомовній країні.
Огнян Димитров

15
Я переживаю регулярні вирази. Я знаю, що синтаксису ніколи не запам’ятаю. Навіть якщо я вивчу це, незабаром настане час, коли це знову забудеться.
Sentinel

1
@Phil. Можливо, але до цього часу я буду делегувати того, хто знає регулярні вирази ;-)
Sentinel

3
Кажуть, "якщо ви вирішите проблему, використовуючи регулярні вирази, то у вас є дві проблеми".
О. Джонс

205

У .NET 4.0 ви можете використовувати LINQ:

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

yourText.Allприпинить виконання та поверне falseперші char.IsLetterOrDigitзвіти, falseоскільки договір Allне може бути виконаний.

Примітка! ця відповідь не суворо перевіряє буквено-цифрові показники (як правило, це AZ, az і 0-9). Ця відповідь дозволяє на зразок місцевих символів åäö.

Оновлення 2018-01-29

Синтаксис вище працює лише тоді, коли ви використовуєте єдиний метод, який має єдиний аргумент правильного типу (у цьому випадку char).

Щоб використовувати декілька умов, потрібно написати так:

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

1
Я був би здивований, якби це не набагато швидше. Жодного регулярного вираження, який не можна складати чи оцінювати, просто просте порівняння.
jgauffin

3
Тепер це просто красиво, просто і просто.
Sentinel

3
Не вдасться це зробити, якщо ви хочете переконатися, що вашText безумовно буквено-цифровий? Це можуть бути або всі цифри, або всі алфавіти, але все ще задовольняють цій умові.
itsbalur

2
@itsbalur: Так, але це не було питання.
jgauffin

2
Я думаю, що ця відповідь просто помилкова, якщо буквено-цифровий набір є AZ, az і 0-9, оскільки це охоплює весь діапазон букв та цифр Unicode, включаючи не латинські символи. Наприклад, char.IsLetterOrDigit('ก')повернеться true. csharppad.com/gist/f96a6062f9f8f4e974f222ce313df8ca
tia

34

Ви можете це зробити легко за допомогою функції розширення, а не регулярного вираження ...

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

За коментар :) ...

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
Це може бути справою смаку, але я б висловив цикл як "foreach (char c in str) {...}". Чи буде пуста рядок вважатись ОК, залежить від програми, тож я б вийняв це. Я також не вкладав би 6 порожніх рядків у такий тривіальний режим, але я думаю, що це стиль C # / Java / C ++ - кодери, здається, платять за нерухомість екрану. У будь-якому випадку це правильний напрямок, тому +1.
Svante

3
Я думаю , що ми хотіли б використовувати IsDigit в цій ситуації, а не IsNumber - IsNumber повертає істину для цифр, або для речей , які виглядають як числа (дробу, римські цифри і т.д.; См msdn.microsoft.com/ en-us / library / yk2b3t2y.aspx ). Враховуючи це, і якщо хтось почував себе особливо злим, можна ще більше стиснути вміст IsAlphaNum: return string.IsNullOrEmpty (str)? false: str.ToCharArray (). Усі (Char.IsLetterOrDigit);
стек

4
Зауважте, що Char.IsLetter оцінить істинне для "літер", відмінних від a-zA-Z. Наприклад, японські あ, китайські 的, корейські 한 тощо вважаються Unicode "літерами". Якщо це ваш намір, то добре, але судячи з різних виразів виразів в інших відповідях, це, швидше за все, не те, що більшість вважають альфа [числовим].
Доно

У моєму випадку, крім IsLetter та IsNumber, мені також знадобився IsWhiteSpace, тому я додав його у свій код, і він працював ідеально!
Ben Junior

використовувати char.IsLetterOrDigitзамість IsLetter + IsNumber
nick_n_a

17

Хоча я думаю, що рішення, що базується на регулярних виразках, мабуть, я б пішов шляхом, я би спокусився інкапсулювати це типом.

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

Тепер, коли вам потрібна перевірена строка, ви можете мати підпис методу, який вимагає AlphaNumericString, і знати, що якщо ви отримаєте його, він дійсний (крім нуля). Якщо хтось спробує передати неперевірену рядок, це створить помилку компілятора.

Ви можете отримати більш фантазійні та реалізувати всі оператори рівності, або явний переклад на AlphaNumericString з простого рядка ol ', якщо вам все одно.


Я ніколи не бачив такого підходу, але мені подобається ясність наміру та ваше обгрунтування. +1.
Cory House

1
Це для мене нове. Я намагаюся розібратися в static public implicit operator stringчастині
Хассан Гюльзар

8

Мені потрібно було перевірити AZ, az, 0-9; без регулярного вираження (навіть якщо ОП просить повторно виразити).

Тут поєднуються різні відповіді та коментарі та обговорення з https://stackoverflow.com/a/9975693/292060 , це тести на букву чи цифру, уникаючи інших літер мови та уникаючи інших цифр, таких як символи дробу.

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

4

^\w+$ дозволить a-zA-Z0-9_

Використовуйте ^[a-zA-Z0-9]+$для заборони підкреслення.

Зауважте, що обоє вимагають, щоб рядок не був порожнім. Використання *замість +дозволяє пусті рядки.


як я можу змінити ваш ^ \ w + $, щоб дозволити "-" тире?
Ніл Девіс

@NealDavis^[\w-]+$
Zafer

2

Щоб перевірити, чи рядок є комбінацією букв і цифр, ви можете переписати відповідь @jgauffin наступним чином, використовуючи .NET 4.0 та LINQ:

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

Це буде неправильно розпізнати рядок, що містить інші символи разом з буквено-цифровими ...
nsimeonov

1

Відповідь така ж, як і тут .

Якщо ви хочете A-z 0-9перевірити ASCII без повторного вибору , ви не можете використовувати його char.IsLetterOrDigit()як інші символи Unicode.

Що ви можете зробити, це перевірити діапазон коду символів.

  • 48 -> 57 - числові
  • 65 -> 90 - великі літери
  • 97 -> 122 - малі літери

Далі - трохи більш детально, але це для зручності розуміння, а не для кодового гольфу.

    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

На основі відповіді клетуса ви можете створити нове розширення.

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

Я раджу не залежати від готового і вбудованого коду в .NET рамках, спробуйте підняти нове рішення .. це те, що я роблю ..

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
Чи можете ви, будь ласка, додали пояснення до свого коду, просто демпінговий код тут, як правило, нахмурився
Дракен

Також вони попросили регулярних виразів, це не регулярні вирази
Дракен

Дякую за коментар та зауваження .. як я порадив, що у мене є власний підхід до написання коду.
Махді Аль Араді

5
Ваш коментар щодо того, що не покладатися на код попереднього збирання char.IsNumber().
Дракен

4
Цей код - чудовий приклад того, чому винаходити його самостійно - це така погана ідея - це насправді не те, що ти хотів зробити! (Рядок "@ 1a" поверне вірно неправильно, рядок "a" повернеться помилковим)
Flexo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.