Как я могу создать RegEx в PHP, который принимает только 3-9 букв (верхний регистр) и 5-50 чисел?
Я не так хорош в регулярных выражениях. Но это не работает:
/[AZ]{3,9}[0-9]{5,50}/
Например, он соответствует ABC12345
но не A12345BC
Есть идеи?
Это классическая проблема типа «проверка пароля». Для этого «грубый рецепт» – проверить каждое условие с помощью lookahead, затем мы сопоставим все.
^(?=(?:[^AZ]*[AZ]){3,9}[^AZ]*$)(?=(?:[^0-9]*[0-9]){5,50}[^0-9]*$)[A-Z0-9]*$
Я объясню это ниже, но вот вариант, который я оставлю вам для выяснения.
^(?=(?:[^AZ]*[AZ]){3,9}[0-9]*$)(?=(?:[^0-9]*[0-9]){5,50}[AZ]*$).*$
Давайте посмотрим на первое регулярное выражение по частям.
[A-Z0-9]*
соответствует всей строке (если она состоит только из прописных ASCII букв и цифр). (Спасибо @TimPietzcker за то, что я спал за рулем, чтобы начать с точечной звезды.) Как работают взгляды?
(?:[^AZ]*[AZ]){3,9}[^AZ]*$)
утверждает, что в текущей позиции, то есть в начале строки, мы можем сопоставить «любое количество символов, которые не являются заглавными буквами, за которыми следует одна прописная буква ", от 3 до 9 раз. Это гарантирует, что у нас достаточно заглавных букв. Обратите внимание, что {3,9}
является жадным, поэтому мы будем сопоставлять как можно больше заглавных букв. Но мы не хотим сопоставлять больше, чем мы хотим разрешить, поэтому после выражения, определяемого по {3,9}
, контрольная проверка проверяет, что мы можем сопоставить «ноль или любое число» символов, которые не являются заглавной буквой, до тех пор, пока конец строки, помеченный якорем $
.
Второй взгляд работает аналогичным образом.
Для более подробного объяснения этого метода вы можете ознакомиться с разделом проверки пароля этой страницы о регулярных выражениях регулярных выражений .
В случае, если вас это интересует, здесь приведено объяснение метода.
^ the beginning of the string (?= look ahead to see if there is: (?: group, but do not capture (between 3 and 9 times) [^AZ]* any character except: 'A' to 'Z' (0 or more times) [AZ] any character of: 'A' to 'Z' ){3,9} end of grouping [^AZ]* any character except: 'A' to 'Z' (0 or more times) $ before an optional \n, and the end of the string ) end of look-ahead (?= look ahead to see if there is: (?: group, but do not capture (between 5 and 50 times) [^0-9]* any character except: '0' to '9' (0 or more times) [0-9] any character of: '0' to '9' ){5,50} end of grouping [^0-9]* any character except: '0' to '9' (0 or more times) $ before an optional \n, and the end of the string ) end of look-ahead [A-Z0-9]* any character of: 'A' to 'Z', '0' to '9' (0 or more times) $ before an optional \n, and the end of the string
Это ваша проблема? http://regexr.com/38pn0
Если это так, вам нужно привязать выражение к началу и концу строки:
/^[AZ]{3,9}[0-9]{5,50}$/
См. Результат: http://regexr.com/38pmt (нет совпадений)