Regular Expression Patterns

owlThis is a quick, look-up of pre-constructed regular expression patterns you can use while validating forms and working with the Internet.  A cheat sheet to speed up your coding.  Each of these has been tested to work with PHP functions.

If you would like to test any of these patterns yourself with an on-line tester,  I recommend the Regular Expression Test Tool, located here.  To test, drop the starting and ending quotes in the $pattern variable and paste /../ into the tester.

Validating Forms

It's normal to place restrictions on usernames, as opposed to first and last names. This pattern must have 8 to 25 alphanumeric characters, and is allowed to have _ or - between the characters, but no other punctualtion is allowed.  It treats spaces as separate words and will only match words from 8 to 25 characters.

$pattern ="/[[:alnum:]_-]{8,25}/";

Addresses with PO Boxes
Matches: Box or box and that's it.

$pattern = "/[Bb]ox/";

US Postal Zip Codes
Must have 5 digts. and it may have a - with 4 digits, that's it. No other characters allowed.  This will not validate Canadian or UK postal codes.

$pattern = "/^[0-9]{5}(?:-[0-9]{4})?$/";

Canadian Zip Codes
Candian postal codes must have two groups of 3 alphanumerics with a space in the middle.  The first letter may not start with DFIOQUW or Z. A good number is: "K2A 9B3"

$pattern = "/^[^DFIOQUWZdfioqwz][0-9][[:alpha:]] [0-9][[:alpha:]][0-9]/";

U.K. Postcodes
Must have 5-8 alphanumeric characters separated by a space that starts with a letter. Valid codes are: "DN55 1PT" and "B33 8TH" for example.

$pattern = "/^[[:alpha:]]{1,2}[0-9][[:alnum:]]? [0-9][[:alpha:]][[:alpha:]]/";

North American Phone Numbers
Must be 10 digits. Digits can be grouped as 3 3 4 digits and separated with a . - () or spaces. This is a good pattern to use the preg_match_all to separate the numbers into groups.

$pattern = "/^(\(?[0-9]{3}\)?)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})?/";

Format North American Phone Numbers to a set Format
Use preg_replace with the above pattern. If it's a valid number, in this pattern, it is formatted to:  (123) 456-7899

$replacement = "($1) $2-$3";

International phone numbers
International numbers start with a + followed by country code and national number. Must have a +, numbers must be at least 7 digits, and can not exceed 15 digits.

$pattern = "/^\+(?:[0-9] ?){6,14}[0-9]$/";

Email addresses
Before the @, it allows multiple numbers, upper and lower letters, and . _ % - and that's it. You must have a @.  After the @, you must have at least one dot, but not 2 dots together, and the after the final . only 2-6 letters to match both 2 digit country codes and the 6 digit .museam.

$pattern = "/[A-Za-z0-9._%-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/";

Date and Time

Date Formats
Match m/d/yy or mm/dd/yyyy allowing 1 or 2 digits for day and month and 2 or 4 digits for year. This is a good one to use with preg_match_all to pull dates out of the group. This will match years of 4 or 2 digits starting with 00 but not just a single digit for the year.

$pattern = "/^(1[0-2]|0?[1-9])\/(3[01]|[12][0-9]|0?[1-9])\/(?:[0-9]{2})?([0-9]{2})/";

If you require leading zeros and a 4 digit year, try this pattern. This requires the format: mm/dd/yyyy.  If you want to see the output of preg_match_all multidimensional array, my newchk utility could help you when you only want a part of the year.

$pattern = "/^(?:(1[0-2]|0[1-9])\/(3[01]|[12][0-9]|0[1-9])|(3[0-1]||12[0-9]|0[1-9])\/(1[0-2]|0[1-9]))\/([0-9]{4})/";

If you're searching through text for dates, as opposed to verifying form entries,  you'll need to use the /b word delimiter on each side of the pattern.  That goes for all the rest of these patterns, also.

$pattern = "/\b(?:(1[0-2]|0[1-9])\/(3[01]|[12][0-9]|0[1-9])|(3[0-1]||12[0-9]|0[1-9])\/(1[0-2]|0[1-9]))\/([0-9]{4})\b/";

Hours:Minutes:Seconds for a 24 hour or 12 hour clock.  Preg_match_all can break this into an array where you can pull the hours out.

$pattern = "/^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/":


A combination of upper and lower case letters and numbers and at least 8 characters, but not more than 25 characters,  No control characters.

$pattern = "/^(?=.*[[:alnum:]]).{8,25}/";

And with control characters, but not quotes or | which could lead to SQL injection

$pattern = "/^(?=.*[[:alnum:]]|[~!@#$%^&*()-_=+]).{8,25}/";

U.S. Currency
Make the $ sign and any commas optional. There must be a . with 2 decimals
It will recognize $.90, $0.90, $002,456.23, and $ 23.13 with a space after the $ sign.

$pattern = "/^\$ ?([0-9]{0,3}(,[0-9]{0,3})*|[0-9]+)(\.[0-9][0-9])$/";

Credit Cards
First, use preg_replace to strip out the spaces and -'s between the numbers.

$pattern = "/[ -]/";
$replacement = '';
$cleanccnumber = $preg_replace($pattern, $replacement, $ccnumber)

The four major credit card companies (Visa, MasterCard, Discover, Amex) all have different number formats. Visa 16 digits starting with a 4, Mastercard 16 digits starting with 51-55, Discover 16 digits starting with 6011 or 15 digits starting with 5, Amex 15 digits starting with 34 or 37. This checks all these combinations for each type of card.

$pattern = "/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011)[0-9]{12}|5([0-9][0-9])[0-9]{12}|3(?:[47][0-9]{13}))?/";

Credit Card Security Code
Three numbers for all cards, except Amex has four numbers.

$pattern = "/^[0-9]{3,4}$/";

Credit Card Expire Date
Usually are 2 digit month and 2 digit year, but normally done with a drop down menu for validation.

Social Security Number
Nine digit numbers in the format of 999-99-9999.  The first three digits are not 000, 666, or 900 to 999. The other two groups can not be 00 or 0000.  Everything else works.

$pattern = "/^(?!000|666|9[0-9]{2})[0-9]{3}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$/";

Federal Tax ID Number
EIN numbers are 9 digit numbers in the format of 99-9999999.

$pattern = "/[0-9]{2}-[0-9]{7}/";

U.S. Passport Number
Must be between six to nine digits all together.

$pattern = "/^[0-9]{6,9}$/";


IPv4 Address
IP address are 4 groups of 3 digits, between 0 - 255, like so, or theoretically they could be

$pattern =  "/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/";

IPv6 Addresses
The new IPv6 addresses consists of eight 16-bit words, as 4 hexadecimal characters each, and delimited by colons. Leading zeros are optional, for example: "1762:1230:EFAC:220:2:B03:1:AF18"

$pattern = "/^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i";

Domain Names
This will account for both domesitic and international domain names, for example:

$pattern = "/^(https?|ftp|file):\/\/.+$/i";

My intent is to gradually add to this list over time.  If any one would like to add a pattern to the list, please put them in a comment, and I will be happy to expand the list for others to use.

Comments are closed.