Как проверить имя пользователя с регулярным выражением?
Это похоже на правила, которые я определил, но я только начинаю изучать регулярное выражение сегодня, поэтому мне интересно, правильно ли оно.
Правила:
- Имена пользователей могут состоять из нижнего регистра
и столицы
- Имена пользователей могут состоять из буквенно-цифровых
символы
- Имена пользователей могут состоять из подчеркивания
и дефисы и пространства
- Не может быть двух символов подчеркивания, двух подстроек
или два пробела подряд
- Не может быть подчеркивания, hypen или
пространство в начале или конце
Шаблон регулярного выражения:
/^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$/
Ответы
Ответ 1
Спецификации в вопросе не очень ясны, поэтому я просто предполагаю, что строка может содержать только буквы и цифры ASCII с дефисами, подчеркиваниями и пробелами в качестве внутренних разделителей. Мясо проблемы заключается в том, что первый и последний символы не являются разделителями и что не более одного разделителя подряд (эта часть кажется ясной, во всяком случае). Вот простейший способ:
/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/
После сопоставления одного или нескольких буквенно-цифровых символов, если есть разделитель, за ним следует одна или несколько буквенно-цифровых символов; повторите по мере необходимости.
Посмотрите на регулярные выражения из некоторых других ответов.
/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/
Это фактически то же самое (если ваш аромат регулярного выражения поддерживает нотацию символьного класса POSIX), но зачем делать разделитель необязательным? Единственная причина, по которой вы были в этой части регулярного выражения, в первую очередь, это наличие разделителя или другого недопустимого символа.
/^[a-zA-Z0-9]+([_\s\-]?[a-zA-Z0-9])*$/
С другой стороны, это работает только потому, что разделитель является необязательным. После первого разделителя он может соответствовать только одному буквенно-цифровому за раз. Чтобы соответствовать больше, он должен повторять всю группу: нулевые разделители, за которыми следует один буквенно-цифровой, снова и снова. Если второй [a-zA-Z0-9]
сопровождался знаком плюса, он мог бы найти совпадение по гораздо более прямому маршруту.
/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/
Это использует неограниченный lookbehind, который является очень редкой функцией, но вы можете использовать lookahead для того же эффекта:
/^(?!.*[_\s-]{2,})[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9]$/
Это выполняет, по сути, отдельный поиск двух последовательных разделителей и не соответствует совпадению, если он находит его. Основной орган тогда должен только удостовериться, что все символы являются алфавитумерами или разделителями, причем первая и последняя являются буквенно-цифровыми. Поскольку эти два требуются, имя должно содержать не менее двух символов.
/^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$/
Это ваше собственное регулярное выражение, и оно требует, чтобы строка начиналась и заканчивалась двумя буквенно-цифровыми символами, и если в строке есть два разделителя, между ними должно быть ровно два алфавитумера. Таким образом, ab
, ab-cd
и ab-cd-ef
будут совпадать, но a
, a-b
и a-b-c
не будут.
Кроме того, как отмечали некоторые из комментаторов, (_|-| )
в вашем регулярном выражении должен быть [-_ ]
. Эта часть не является неправильной, но если у вас есть выбор между чередованием и символьным классом, вы всегда должны идти с классом символов: они более эффективны, а также более читаемы.
Опять же, меня не волнует вопрос о том, должен ли "буквенно-цифровой" включать не-ASCII-символы или точный смысл "пространства", просто как обеспечить соблюдение политики несмежных внутренних разделителей с регулярным выражением.
Ответ 2
Вы можете упростить регулярное выражение:
/^[a-zA-Z0-9]+([_ -]?[a-zA-Z0-9])*$/
Визуализировано с помощью Regexper:
![Визуализация регулярного выражения проверки имени пользователя.]()
Как вы можете видеть, имя пользователя всегда должно начинаться с буквенно-цифрового символа. Специальные символы (_
,
, -
) должны сопровождаться буквенно-цифровым символом. Последний символ должен быть буквенно-цифровым символом.
Ответ 3
([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*
- 0 или более повторений букв, dashspace, alphanum.
Таким образом, он будет соответствовать
a_aa_aa_a
но не
aaaaa
Полное regexp не может соответствовать
a_aaaaaaaaa_a for example.
Оглянитесь на то, что вы хотите:
* Usernames can consist of lowercase and capitals or alphanumerica characters
* Usernames can consist of alphanumeric characters
* Usernames can consist of underscore and hyphens and spaces
* Cannot be two underscores, two hypens or two spaces in a row
* Cannot have a underscore, hypen or space at the start or end
Начало простое... просто совпадение с буквенным алфавитом, затем (включение двух в правиле строки) a (alphanum или dashspace) * и снова и снова в алфавите.
Чтобы избежать двух помех в строке, вам, вероятно, нужно понять lookahead/lookbehind.
О, и в отношении другого ответа: Пожалуйста, загрузите Espresso, он ДЕЙСТВИТЕЛЬНО поможет вам разобраться в этом.
Ответ 4
Я предлагаю написать некоторые модульные тесты, чтобы поместить Regex через него. Это также поможет через несколько месяцев, когда вы обнаружите проблему с Regex и должны ее обновить.
Ответ 5
-
Alphanumerical - это не только [a-zA-Z0-9]
, он акцентирован, кириллица, греческий и другие буквы, которые могут использоваться в имени пользователя.
-
(_|-| )
может быть заменен на [-_ ]
класс символов
Ответ 6
Использование класса символов POSIX для буквенно-цифровых символов, чтобы заставить его работать с акцентированными и другими иностранными алфавитными символами:
/^[[:alnum:]]+([-_ ]?[[:alnum:]])*$/
Более эффективный (предотвращает захват):
/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/
Они также предотвращают последовательность из более чем одного пробела/дефиса/подчеркивания в комбинации.
Из вашей спецификации не следует, желательно ли это, но ваше собственное регулярное выражение
кажется, что это то, что вы хотите.
Ответ 7
Еще одна рекомендация для Expresso 3.0 - очень проста в использовании и создавать строки с.
Ответ 8
Ваше регулярное выражение не работает. Жесткая часть - это проверка последовательных пробелов/дефисов. Вы можете использовать этот, который использует look-behind:
/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/
Ответ 9
По внешнему виду это правило не будет соответствовать чему-то вроде "a_bc", "ab_c", "a_b" или "a_b_c".
Попробуйте: /^[a-zA-Z0-9]+([_\s\-]?[a-zA-Z0-9])*$/
который соответствует указанным выше случаям, но не представляет собой комбинацию пробелов, тире или подчеркивания рядом друг с другом. Например: "_-" или "_" не разрешены.
Ответ 10
По моему мнению, было бы лучше добавить ограниченную область применения к этой модели.
[a-zA-Z0-9] + ([_ -]? [a-zA-Z0-9]) {5,40} $
![enter image description here]()