PHP: RegEx для строки с 3-9 буквами и 5-50 числами

Как я могу создать 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]*$).*$ 

Давайте посмотрим на первое регулярное выражение по частям.

  1. Мы привязываем регулярное выражение между заголовком строки ^ и завершением строковых $ assertions, гарантируя, что совпадение (если есть) – целая строка.
  2. У нас есть два взгляда: один для заглавных букв, один для цифр.
  3. После просмотра [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 (нет совпадений)