Регулярное выражение для проверки имен пользователей, состоящих хотя бы из одной буквы и не содержащих специальных символов

#ruby-on-rails #regex

#ruby-on-rails #регулярное выражение

Вопрос:

Я пытаюсь написать проверку имени пользователя, которая имеет следующие ограничения:

  1. Должно содержать как минимум 1 букву (a-zA-Z)
  2. Может содержать только цифры, буквы или подчеркивания

Допустимы следующие примеры: abc123, my_name, 12345a

Следующие примеры недопустимы: 123456, my_name!, _1235

Я нашел кое-что об использовании положительных предвидений для ограничения буквы: (?=.*[a-zA-Z]), и похоже, что для второго ограничения может быть какой-то отрицательный предвидение, но я не уверен, как объединить их в одно регулярное выражение. (Примечание… Я не совсем понимаю, что делает часть .* внутри предварительного просмотра …)

Это что-то вроде этого: /(?=.*[a-zA-Z])(?!.*[^a-zA-Z0-9_])/

Редактировать:

Поскольку в вопросе запрашивается регулярное выражение, ответ, который я принимаю, таков:

  /^[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*$/
  

Однако то, что я на самом деле собираюсь реализовать, — это предложение Брайана Оукли разделить его на несколько проверок меньшего размера. Это упрощает чтение и расширение в будущем в случае изменения требований. Спасибо всем!

И поскольку я пометил это ruby-on-rails, я включу код, который я на самом деле использую:

 validate :username_format    

def username_format
  has_one_letter = username =~ /[a-zA-Z]/
  all_valid_characters = username =~ /^[a-zA-Z0-9_] $/
  errors.add(:username, "must have at least one letter and contain only letters, digits, or underscores") unless (has_one_letter and all_valid_characters)
end
  

Ответ №1:

/^[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*$/ : за 0 или более допустимыми символами следует один алфавитный, за которым следует 0 или более допустимых символов, которые должны быть как началом, так и концом строки.

Комментарии:

1. Мило, в первом тесте отсутствует _ для 0 или более допустимых значений, но в остальном это работает!

Ответ №2:

Легко проверить, содержит ли шаблон какие-либо недопустимые символы, и легко проверить, есть ли хотя бы одна буква. Попытка сделать все это в одном регулярном выражении затруднит понимание вашего кода.

Я рекомендую провести два теста. Поместите тесты в функции, чтобы сделать ваш код абсолютно мертвым — простым для понимания:

 if no_illegal_characters(string) amp;amp; contains_one_alpha(string) {
    ...
}
  

Для первого вы можете использовать шаблон ^[a-zA-Z0-9_] $ , а для второго вы можете использовать [a-zA-Z] .

Если вам не нравятся дополнительные функции, это нормально, просто не пытайтесь решить проблему с помощью одного сложного для чтения регулярного выражения. За втискивание как можно большего количества функций в одно выражение бонусные баллы не начисляются.

Комментарии:

1. В твоем регулярном выражении «no_illegal_characters()» обнаружена небольшая ошибка, Брайан. На данный момент регулярное выражение гласит: «длина строки должна составлять всего 1 символ от начала до конца». Вместо ^[a-zA-Z0-9_]$ этого должно быть ^[a-zA-Z0-9_] $ .

2. Спасибо @wyatt, я изменил выражение, включив

Ответ №3:

самое простое регулярное выражение, которое решает вашу проблему, это:

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

Я рекомендую вам попробовать это вживую наhttp://rubular.com /

Комментарии:

1. Это не идеальное решение: оно не допускает 12345a.

2. Похоже, что это очень близко, но также наложено ограничение, что оно должно начинаться с буквы, поэтому 12345a не проходит.

3. Извините, я думал, что 12345a неверен: правильный /^[a-zA-Z0-9][a-zA-Z0-9_] *$/

4. @Ireneusz Skrobis: нет, это тоже не сработает, потому что это будет соответствовать строке, содержащей только число (т. Е.: это будет соответствовать «42»)

5. какой облом: P но, похоже, Ши Леви опубликовал правильный ответ, не так ли?