PO Box Regular Expression Validation

Here's my code, but I can't ever trigger the alert.

$(document).ready( function (){
    $("[id*='txtAddress1S']").blur(function() {
        var pattern = new RegExp('\b[P|p]*(OST|ost)*\.*\s*[O|o|0]*(ffice|FFICE)*\.*\s*[B|b][O|o|0][X|x]\b');
        if ($("[id*='txtAddress1S']").val().match(pattern)) {
            alert('We are unable to ship to a Post Office Box.\nPlease provide a different shipping address.'); 




In javascript, you have to escape your slashes:

var pattern = new RegExp('\\b[P|p]*(OST|ost)*\\.*\\s*[O|o|0]*(ffice|FFICE)*\\.*\\s*[B|b][O|o|0][X|x]\\b');

Also, you could reduce your pattern a bit by using case-insensitive matching:

var pattern = new RegExp('\\b[p]*(ost)*\\.*\\s*[o|0]*(ffice)*\\.*\\s*b[o|0]x\\b', 'i');

Note: Your regex also matches on addresses such as:

  • 123 Poor Box Road
  • 123 Harpo Box Street

I would suggest also checking for a number in the string. Perhaps this pattern from a previous answer would be of some help:

var pattern = new RegExp('[PO.]*\\s?B(ox)?.*\\d+', 'i');

(it won't match on "Post Office" spelled out, or the numeric replacements.. but it's a start.)


I tried several PO Box RegExp patterns found on the internet including the ones posted on Stack Overflow, none of them passed our test requirements. Hence, I posted our RegExp below and our test sets:

var poBox = /^ *((#\d+)|((box|bin)[-. \/\\]?\d+)|(.*p[ \.]? ?(o|0)[-. \/\\]? *-?((box|bin)|b|(#|num)?\d+))|(p(ost)? *(o(ff(ice)?)?)? *((box|bin)|b)? *\d+)|(p *-?\/?(o)? *-?box)|post office box|((box|bin)|b) *(number|num|#)? *\d+|(num|number|#) *\d+)/i;

var matches = [ //"box" can be substituted for "bin" 
    "Box 123", 
    "HC73 P.O. Box 217", 
    "P O Box125", 
    "P. O. Box", 
    "P.O 123", 
    "P.O. Box 123", 
    "P.O. Box", 
    "P.O.B 123",
    "P.O.B. 123", 
    "P0 Box", 
    "PO 123", 
    "PO Box N", 
    "PO Box", 
    "POB 123", 
    "Po Box", 
    "Post 123", 
    "Post Box 123", 
    "Post Office Box 123", 
    "Post Office Box", 
    "box #123", 
    "box 122", 
    "box 123", 
    "number 123", 
    "p box", 
    "p-o box", 
    "p.o box", 
    "p.o. box", 
    "p.o.b. #123", 
    "p/o box", 
    "po #123", 
    "po box 123", 
    "po box", 
    "po num123", 
    "post office box" 

var nonMatches = [ 
    "The Postal Road", 
    "Box Hill", 
    "123 Some Street", 
    "Controller's Office", 
    "pollo St.", 
    "123 box canyon rd", 
    "777 Post Oak Blvd", 
    "PSC 477 Box 396", 
    "RR 1 Box 1020" 

With Javascript its easier to use a regex literal like so:

var pattern = /\b(?:p\.?\s*o\.?|post\s+office)\s+box\b/i;

(No backslashes required!)


This is what i have used accounting for spaces and case insensitive:


var pattern = /\bP(ost|ostal)?([ \.]*(O|0)(ffice)?)?([ \.]*Box)?\b/i;
  • fail - po box
  • fail - p.o. box
  • fail - po bo
  • fail - post office box
  • fail - P.O. Box
  • fail - PO. Box
  • fail - PO Box
  • fail - POBox
  • fail - P O Box
  • fail - P.O Box
  • fail - PO
  • fail - Postal Box
  • fail - Post Office Box
  • pass - poop box
  • pass - pony box

This one is working pretty well for us. (php preg_match)

$pattern = '!p(ost)?\.?\s*o(ffice)?\.?(box|\s|$)!i';

Its worked for me,

var poRegex = /\bP(ost|ostal)?([ \.]*O(ffice)?)?([ \.]*Box)?\b/i;

Here's one that matches 'POB', 'PO Box'and 'Post Office Box'. Pattern:


It's a modification of @drudge's solution.


The regex provided above is accepting PO box which is correct. Modified Regex not to accept is:

var pattern = /^ *(?!(#\d+)|((box|bin)[-. \/\\]?\d+)|(.*p[ \.]? ?(o|0)[-. \/\\]? *-?((box|bin)|b|(#|num)?\d+))|(p(ost)? *(o(ff(ice)?)?)? *((box|bin)|b)? *\d+)|(p *-?\/?(o)? *-?box)|post office box|((box|bin)|b) *(number|num|#)? *\d+|(num|number|#)|(?![a-zA-Z0-9\x20'#,]) *\d+)/i;

We ran into false positive PO Boxes after using @Dathan's answer in production for a few months. This simplified version ensures the pattern is followed by a number so won't match things like "Expo Blvd". It also allows things like "#123" and "B1" commonly found in address2 fields for apartment/unit/suite numbers. You can play around with it and add your own test cases here: https://regex101.com/r/7ZUQFl/2

const re = /^\s*(.*((p|post)[-.\s]*(o|off|office)[-.\s]*(b|box|bin)[-.\s]*)|.*((p|post)[-.\s]*(o|off|office)[-.\s]*)|.*((p|post)[-.\s]*(b|box|bin)[-.\s]*)|(box|bin)[-.\s]*)(#|n|num|number)?\s*\d+/i;
const matches = [
  "post office box 1",
  "post office b 1",
  "post off box 1",
  "post off b 1",
  "post o box 1",
  "post o b 1",
  "p office box 1",
  "p office b 1",
  "p off box 1",
  "p off b 1",
  "p o box 1",
  "pob #1",
  "pob num1",
  "pob number1",
  "foo pob1",
  "box #1",
  "po 1",
  "pb 1"
const nonMatches = [ 
  "Expo Blvd",
  "Rural Route Box 1",
  "Army Post 1",
  "Number 1",
  "Num 1"

I found a pattern that works for most realistic post office addresses. Also had to fall to this after getting false positive with @jonathan-marzullo's answer for Rural Route Post 1 which is not a postal address.

My pattern is

pattern = P([.]?(O|0)[.]?|ost|ostal).((O|0)ffice.)?Box{1}\b/i

Matches for the following cases:

PO Box
P.O. Box
PO. Box
po box
P.o box
po box
p.o. box
post office box
P.O. Box
PO. Box
PO Box
Postal Box
Post Office Box
P.O Box
post office box 1
postal office box 1
postal box 1

Doesn't match the following cases:

post office b 1
post off box 1
post off b 1
post o box 1
post o b 1
p office box 1
p office b 1
p off box 1
p off b 1
p o box 1
pob #1
pob num1
pob number1
foo pob1
box #1
po 1
pb 1
Expo Blvd
Rural Route Box 1
Army Post 1
postal office 1
poop box
pony box
P O Box
po bo



You just need to start the regex with ^, like: ^\b[P|p]......


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.