Как я могу проверить строку, чтобы в ней разрешались только буквенно-цифровые символы?

117

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

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

mrblah
источник

Ответы:

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
@Фил. Возможно, но к тому времени я буду делегировать полномочия тому, кто знает регулярные выражения ;-)
Sentinel
3
Было сказано: «Если вы решаете проблему с помощью регулярных выражений, у вас возникают две проблемы».
O. Jones
205

В .NET 4.0 вы можете использовать LINQ:

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

yourText.Allпрекратит выполнение и вернет отчеты falseв первый раз, так как тогда договор не может быть выполнен.char.IsLetterOrDigitfalseAll

Заметка! в этом ответе строго не проверяются буквенно-цифровые символы (обычно это AZ, az и 0-9). Этот ответ позволяет местным персонажам вроде åäö.

Обновление 2018-01-29

Приведенный выше синтаксис работает только при использовании одного метода с единственным аргументом правильного типа (в данном случае char).

Чтобы использовать несколько условий, вам нужно написать так:

if (yourText.All(x => char.IsLetterOrDigit(x) || char.IsWhiteSpace(x)))
{
}
jgauffin
источник
1
Я был бы удивлен, если это не намного быстрее. Никаких регулярных выражений для компиляции или оценки, просто простое сравнение.
jgauffin
3
Теперь это просто красиво, ясно и просто.
Sentinel
3
Разве это не подведет, если вы хотите убедиться, что ваш текст определенно буквенно-цифровой? Это могут быть как все цифры, так и все буквы, но все же удовлетворять этому условию.
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)));
}
JP Alioto
источник
2
Возможно, это дело вкуса, но я бы выразил цикл как «foreach (char c in str) {...}». Будет ли пустая строка считаться ОК, зависит от приложения, поэтому я бы убрал это. Я бы также не стал вкладывать 6 пустых строк в такую ​​тривиальную процедуру, но я предполагаю, что это стиль C # / Java / C ++ - кодировщикам, похоже, платят за счет недвижимости на экране. В любом случае, это правильное направление, так что +1.
Svante
3
Я бы подумал, что в этой ситуации мы хотели бы использовать IsDigit, а не IsNumber - IsNumber вернет true для цифр или для вещей, которые выглядят как числа (дроби, римские цифры и т.д .; см. Msdn.microsoft.com/ en-us / library / yk2b3t2y.aspx ). Учитывая это, и если кто-то чувствовал себя особенно злым, можно было бы сжать содержимое IsAlphaNum еще больше: return string.IsNullOrEmpty (str)? false: str.ToCharArray (). All (Char.IsLetterOrDigit);
stack
4
Обратите внимание, что Char.IsLetter будет иметь значение true для «букв», отличных от 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 из простой строки, если вам интересно.

kyoryu
источник
Я никогда не видел такого подхода, но мне нравится ясность намерений и ваше обоснование. +1.
Cory House
1
Для меня это в новинку. Я пытаюсь понять static public implicit operator stringчасть
Хасан Гульзар
8

Мне нужно было проверить AZ, az, 0-9; без регулярного выражения (хотя OP запрашивает регулярное выражение).

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

if (!String.IsNullOrEmpty(testString)
    && testString.All(c => Char.IsLetterOrDigit(c) && (c < 128)))
{
    // Alphanumeric.
}
goodeye
источник
4

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

Используйте, ^[a-zA-Z0-9]+$чтобы запретить подчеркивание.

Обратите внимание, что оба из них требуют, чтобы строка не была пустой. Использование *вместо +разрешает пустые строки.

Питер Ботон
источник
как я могу изменить ваш ^ \ w + $, чтобы он также разрешал символ тире "-"?
Нил Дэвис
@NealDavis^[\w-]+$
Zachafer
2

Чтобы проверить, является ли строка комбинацией букв и цифр, вы можете переписать ответ @jgauffin следующим образом, используя .NET 4.0 и LINQ:

if(!string.IsNullOrWhiteSpace(yourText) && 
yourText.Any(char.IsLetter) && yourText.Any(char.IsDigit))
{
   // do something here
}
Табисо Мофокенг
источник
Это неправильно распознает строку, содержащую другие символы наряду с буквенно-цифровыми ...
nsimeonov 06
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

Основываясь на ответе cletus, вы можете создать новое расширение.

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 framework, попытаться найти новое решение .. это то, что я делаю ..

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
Ваш комментарий о том, что не следует полагаться на код предварительной сборки в .Net, имеет мало смысла, конечно, если вы не должны полагаться на код предварительной сборки, вы не должны использовать этот char.IsNumber()метод, поскольку это предварительно созданный код?
Draken
4
Этот код - отличный пример того, почему изобретать его самому - такая плохая идея - на самом деле он не делает того, что вы хотели! (Строка «@ 1a» вернет истину неправильно, строка «a» вернет ложь)
Flexo