использование конструкции or (a|b
) составляет большую часть этого, и вы начали применять его, так что это хорошее начало.
Вы сделали правило, что это не может начинать с цифры; ничего в спе c об этом не сказано. Кроме того, -
внутри []
имеет особое значение, поэтому избегайте его или убедитесь, что он первый или последний, потому что тогда вам не нужно. Это приводит нас к следующему:
^(\s{8}|[A-Za-z0-9-!& -]{8})$
следующее правило: это должен быть один и тот же специальный символ, если он вообще используется. Учитывая, что есть только 3 специальных символа, может быть проще просто явно перечислить их все:
^(\s{8}|[A-Za-z0-9 -]{8}|[A-Za-z0-9 !]{8}|[A-Za-z0-9 &]{8})$
Далее: не может начинаться с пробела и не может быть все-особенное. Подтверждение отрицательного (что это все специальные символы ISNT) усложняется; взгляд вперед кажется здесь лучшим планом. Это:
^
является регулярным выражением для: «Начало строки». Обратите внимание, что это не «потребляет» персонажа. 1
является регулярным выражением для «здесь будет соответствовать только точный символ« 1 », ничего больше», но при совпадении он также «потребляет» этот символ, тогда как ^
этого не делает. «начало строки» не является концепцией, которую можно использовать.
Это понятие «совпадение может быть неудачным, но в случае успеха ничего не используется» не ограничивается ^
и $
; вы можете написать свой собственный:
(?=abc)
будет соответствовать, если abc
будет соответствовать в этой позиции, , но не потребляет его . Таким образом, регулярное выражение ^(=abc)ab.d$
будет соответствовать входной строке abcd
и ничему другому. Это называется положительный просмотр вперед . (он «смотрит вперед» и соответствует, если видит регулярное выражение в скобках, и терпит неудачу, если нет).
(?!abc)
равно отрицательный просмотр вперед . Он совпадает, если он НЕ видит вещь в скобках. (?!abc)a.c
будет соответствовать входу adc
, но не входу abc
.
(?<=abc)
это положительный просмотр назад . Он совпадает, если предоставленный вами шаблон будет соответствовать так, что совпадение заканчивается в позиции, в которой вы оказались.
(?<!abc)
это отрицательный просмотр назад .
Обратите внимание, что просмотр вперед и назад может быть несколько ограничен, поскольку они могут не допускать шаблонов переменной длины. Но, к счастью, ваши требования позволяют легко ограничиться выкройками фиксированного размера. Таким образом, мы можем ввести: (?![&!-]{8})
как непотребляющую единицу в нашем регулярном выражении, которая не будет соответствовать, если у нас есть все 8 специальных символов.
Мы можем использовать этот трюк и для сбоя в начальном пространстве: (?! )
- это все, что нам нужно для этого.
Давайте заменим \s
, который является пробелом , просто
, который является пробелом (в описании проблемы написано «пробел», а не пробел).
Собираем все вместе:
^( {8}|(?! )(?![&!-]{8})([A-Za-z0-9 -]{8}|[A-Za-z0-9 !]{8}|[A-Za-z0-9 &]{8}))$
Вот:
- 8 пробелов, или ...
- не пробел и не специальный символ из всех 8, тогда
- любой из допустимых символов, любое количество пробелов и любое количество одного из 3 разрешенных специальных символов, как пока у нас их ровно 8 ...
- .. ИЛИ то же самое, что и # 3, но со вторым из трех специальных символов
- .. ИЛИ с третьим из трех .
Подключите их к regex101 вместе с вашими различными примерами «легальных» и «незаконных», и вы можете играть в aro и еще кое-что.
NB: Вы также можете использовать обратные ссылки, чтобы попытаться решить часть этой задачи «разрешен только один специальный символ», но попытка решить часть «не все специальные символы» кажется довольно сложной. громоздко, если вы не можете использовать (отрицательный) просмотр вперед.