正则表达式不起作用,接受几乎所有字母数字组合

Can someone tell me what i'm doing wrong? This is accepting everything as a match.

if (preg_match("/^[A-Z][a-z][a-z][0-9]|[1-9][0-9]|1[0-4][0-9]|15[0-1]:[0-9]|[1-9][0-9]|1[0-6][0-9]|17[0-6]/", $_GET['id']))
 {
 echo "match";
 }
 else
 {
 echo "no match";
 }

i'm wanting it to only match if the 1st letter is a capital A-Z, the 2nd letter a small letter a-z, the third letter a small letter a-z, then a number between 1 and 150, a colon :, Then a number between 1 and 176. It should match Abc150:176 Zyx1:1 But not aBc151:177

Use this:

^[A-Z][a-z]{2}(?:[1-9][0-9]?|1[0-4][0-9]|150):(?:[1-9][0-9]?|1[0-6][0-9]|17[0-6])$

See demo.

  • ^ asserts that we are at the beginning of the string
  • [A-Z][a-z]{2} matches one upper-case and two lower-case letters
  • (?:[1-9][0-9]?|1[0-4][0-9]|150) matches a number from 1 to 150
  • : matches a colon
  • (?:[1-9][0-9]?|1[0-6][0-9]|17[0-6]) matches a number from 1 to 176
  • $ asserts that we are at the end of the string

In php:

$regex = "~^[A-Z][a-z]{2}(?:[1-9][0-9]?|1[0-4][0-9]|150):(?:[1-9][0-9]?|1[0-6][0-9]|17[0-6])$~";
echo (preg_match($regex,$string)) ? "***Match!***" : "No match";

You need to place the expressions around your alternation operator (|) in parens, otherwise it matches EVERYTHING to the left and right. As you have it now, it matches Aaa1 or 10 when you mean Aaa1 or Aaa10. Try:

/^[A-Z][a-z][a-z]([0-9]|[1-9][0-9]|1[0-4][0-9]|15[0-1]):([0-9]|[1-9][0-9]|1[0-6][0-9]|17[0-6])/