Regular Expression patterns for Tracking numbers

Viewed 56406

Does anybody know good place or patterns for checking which company tracking number is the given tracking number for a package. Idea is After scanning a barcode for a package check tracking number with patterns and show which company it was shipped by.

18 Answers

Just thought I would post an update on this as I am working on this to match via jquery and automatically select the appropriate shipping carrier. I compiled a list of the matching regex for my project and I have tested a lot of tracking numbers across UPS FedEX and USPS.

If you come across something which doesn't match, please let me know here via comments and I will try to come up for that as well.

UPS:

/\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b/

FedEX: (3 Different Ones)

/(\b96\d{20}\b)|(\b\d{15}\b)|(\b\d{12}\b)/
/\b((98\d\d\d\d\d?\d\d\d\d|98\d\d) ?\d\d\d\d ?\d\d\d\d( ?\d\d\d)?)\b/
/^[0-9]{15}$/

USPS: (4 Different Ones)

/(\b\d{30}\b)|(\b91\d+\b)|(\b\d{20}\b)/
/^E\D{1}\d{9}\D{2}$|^9\d{15,21}$/
/^91[0-9]+$/
/^[A-Za-z]{2}[0-9]+US$/

Please note that I did not come up with these myself. I simply searched around and compiled the list from different sources, including some which may have been mentioned here.

Thanks

Edit: Fixed missing end delimiter.

I needed something more robust for my use case. I kept running across examples that were incomplete, incorrect, or overly verbose without any improvement in correctness. Hopefully this helps someone else! It covers all of the different formats in the other answers, plus a few more, and doesn't overlap between FedEx and USPS unlike some of the other answers.

Tracking Number Regular Expressions:

USPS/S10:

https://postalpro.usps.com/mnt/glusterfs/2020-02/Pub%20199%20Intelligent%20Mail%20Package%20Barcode%20(IMpb)%20Implementation%20Guide%202020_02_11%20TT%20v6.pdf

\b([A-Z]{2}\d{9}[A-Z]{2}|(420\d{9}(9[2345])?)?\d{20}|(420\d{5})?(9[12345])?(\d{24}|\d{20})|82\d{8})\b

UPS:

\b1Z[A-Z0-9]{16}\b

FedEx:

\b([0-9]{12}|100\d{31}|\d{15}|\d{18}|96\d{20}|96\d{32})\b

Caveats/notes:

  • FedEx SmartPost is [intentionally] categorized as USPS; it can be tracked with either
  • USPS includes S10 format tracking numbers used for international post
  • Tracking numbers have module check bits; these regex's don't check them
  • This was found by reading spec sheets, reading other answers, looking at open source code, etc. It matched ~6,000 tracking numbers I ran it against with 100% accuracy, but I can't be sure it will be correct in all cases.
  • These assume you've removed all whitespace before applying the regex

Example Tracking Numbers

Mostly pulled from:

| Tracking Number                    | Kind                                | Tracking Carrier |
|------------------------------------|-------------------------------------|------------------|
| 03071790000523483741               | USPS 20                             | USPS             |
| 71123456789123456787               | USPS 20                             | USPS             |
| 4201002334249200190132607600833457 | USPS 34v2                           | USPS             |
| 4201028200009261290113185417468510 | USPS 34v2                           | USPS             |
| 420221539101026837331000039521     | USPS 91                             | USPS             |
| 71969010756003077385               | USPS 91                             | USPS             |
| 9505511069605048600624             | USPS 91                             | USPS             |
| 9101123456789000000013             | USPS 91                             | USPS             |
| 92748931507708513018050063         | USPS 91                             | USPS             |
| 9400111201080805483016             | USPS 91                             | USPS             |
| 9361289878700317633795             | USPS 91                             | USPS             |
| 9405803699300124287899             | USPS 91                             | USPS             |
| EK115095696SA                      | S10                                 | USPS             |
| 1Z5R89390357567127                 | UPS                                 | UPS              |
| 1Z879E930346834440                 | UPS                                 | UPS              |
| 1Z410E7W0392751591                 | UPS                                 | UPS              |
| 1Z8V92A70367203024                 | UPS                                 | UPS              |
| 1ZXX3150YW44070023                 | UPS                                 | UPS              |
| 986578788855                       | FedEx Express (12)                  | FedEx            |
| 477179081230                       | FedEx Express (12)                  | FedEx            |
| 799531274483                       | FedEx Express (12)                  | FedEx            |
| 790535312317                       | FedEx Express (12)                  | FedEx            |
| 974367662710                       | FedEx Express (12)                  | FedEx            |
| 1001921334250001000300779017972697 | FedEx Express (34)                  | FedEx            |
| 1001921380360001000300639585804382 | FedEx Express (34)                  | FedEx            |
| 1001901781990001000300617767839437 | FedEx Express (34)                  | FedEx            |
| 1002297871540001000300790695517286 | FedEx Express (34)                  | FedEx            |
| 61299998820821171811               | FedEx SmartPost                     | USPS             |
| 9261292700768711948021             | FedEx SmartPost                     | USPS             |
| 041441760228964                    | FedEx Ground                        | FedEx            |
| 568283610012000                    | FedEx Ground                        | FedEx            |
| 568283610012734                    | FedEx Ground                        | FedEx            |
| 000123450000000027                 | FedEx Ground (SSCC-18)              | FedEx            |
| 9611020987654312345672             | FedEx Ground 96 (22)                | FedEx            |
| 9622001900000000000000776632517510 | FedEx Ground GSN                    | FedEx            |
| 9622001560000000000000794808390594 | FedEx Ground GSN                    | FedEx            |
| 9622001560001234567100794808390594 | FedEx Ground GSN                    | FedEx            |
| 9632001560123456789900794808390594 | FedEx Ground GSN                    | FedEx            |
| 9400100000000000000000             | USPS Tracking                       | USPS             |
| 9205500000000000000000             | Priority Mail                       | USPS             |
| 9407300000000000000000             | Certified Mail                      | USPS             |
| 9303300000000000000000             | Collect On Delivery Hold For Pickup | USPS             |
| 8200000000                         | Global Express Guaranteed           | USPS             |
| EC000000000US                      | Priority Mail Express International | USPS             |
| 9270100000000000000000             | Priority Mail Express               | USPS             |
| EA000000000US                      | Priority Mail Express               | USPS             |
| CP000000000US                      | Priority Mail International         | USPS             |
| 9208800000000000000000             | Registered Mail                     | USPS             |
| 9202100000000000000000             | Signature Confirmation              | USPS             |

You can try these (not guaranteed):

UPS:

\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b

UPS:

\b(1Z ?\d\d\d ?\d\w\w ?\d\d ?\d\d\d\d ?\d\d\d ?\d|[\dT]\d\d\d ?\d\d\d\d ?\d\d\d)\b

USPost:

\b(\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d|\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d)\b

But please test before you use them. I recommend RegexBuddy.

I'm working in an Angular2+ app and just put together a component to handle common US tracking numbers. It tests them using standard JavaScript RegExp's that I put together from this resource HERE & HERE and sets the href on an anchor tag with the tracking link URL if it's good. You don't have to be using Angular or TypeScript to easily adapt this to your application. I tested it out with different dummy numbers and seem to work dynamically so far. Please note, you can also switch out the null in the last else statement with the in-line commented url and it will send you to a Google search.

Any feedback (or if your tracking numbers don't work) please let me know I will update the answer. Thanks!

USAGE IN HTML:

<app-tracking-number [trackNum]="myTrackingNumberInput"></app-tracking-number>

COMPONENT .TS

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-tracking-number',
  templateUrl: './tracking-number.component.html',
  styleUrls: ['./tracking-number.component.scss']
})
export class TrackingNumberComponent implements OnInit {
    @Input() trackNum:string;
    trackNumHref:string = null;
    // Carrier tracking numbers patterns from https://www.iship.com/trackit/info.aspx?info=24 AND https://www.canadapost.ca/web/en/kb/details.page?article=how_to_track_a_packa&cattype=kb&cat=receiving&subcat=tracking
    isUPS:RegExp = new RegExp('^1Z[A-H,J-N,P,R-Z,0-9]{16}$');               // UPS tracking numbers usually begin with "1Z", contain 18 characters, and do not contain the letters "O", "I", or "Q".
    isFedEx:RegExp = new RegExp('^[0-9]{12}$|^[0-9]{15}$');                 // FedEx Express tracking numbers are normally 12 digits long and do not contain letters AND FedEx Ground tracking numbers are normally 15 digits long and do not contain letters.
    isUSPS:RegExp = new RegExp('^[0-9]{20,22}$|^[A-Z]{2}[0-9,A-Z]{9}US$');  // USPS Tracking numbers are normally 20-22 digits long and do not contain letters AND USPS Express Mail tracking numbers are normally 13 characters long, begin with two letters, and end with "US".
    isDHL:RegExp = new RegExp('^[0-9]{10,11}$');                            // DHL tracking numbers are normally 10 or 11 digits long and do not contain letters.
    isCAPost:RegExp = new RegExp('^[0-9]{16}$|^[A-Z]{2}[0-9]{9}[A-Z]{2}$'); // 16 numeric digits (0000 0000 0000 0000) AND 13 numeric and alphabetic characters (AA 000 000 000 AA).

    constructor() { }

    ngOnInit() {
        this.setHref();
    }

    setHref() {
        if(!this.trackNum) this.trackNumHref = null;
        else if(this.isUPS.test(this.trackNum)) this.trackNumHref = `https://wwwapps.ups.com/WebTracking/processInputRequest?AgreeToTermsAndConditions=yes&loc=en_US&tracknum=${this.trackNum}&Requester=trkinppg`;
        else if(this.isFedEx.test(this.trackNum)) this.trackNumHref = `https://www.fedex.com/apps/fedextrack/index.html?tracknumber=${this.trackNum}`;
        else if(this.isUSPS.test(this.trackNum)) this.trackNumHref = `https://tools.usps.com/go/TrackConfirmAction?tLabels=${this.trackNum}`;
        else if(this.isDHL.test(this.trackNum)) this.trackNumHref = `http://www.dhl.com/en/express/tracking.html?AWB=${this.trackNum}&brand=DHL`;
        else if(this.isCAPost.test(this.trackNum)) this.trackNumHref =`https://www.canadapost.ca/trackweb/en#/search?searchFor=${this.trackNum}`;
        else this.trackNumHref = null; // Google search as fallback... `https://www.google.com/search?q=${this.trackNum}`;
    }

}

COMPONENT .HTML

<a *ngIf="trackNumHref" [href]="trackNumHref" target="_blank">{{trackNum}}</a>
<span *ngIf="!trackNumHref">{{trackNum}}</span>

Here is a great resource which captures just about all possibilities and is as tight as I have found:

https://andrewkurochkin.com/blog/code-for-recognizing-delivery-company-by-track

    string[] upsPattern = new string[]
    {
        "^(1Z)[0-9A-Z]{16}$",
        "^(T)+[0-9A-Z]{10}$",
        "^[0-9]{9}$",
        "^[0-9]{26}$"
    };

    string[] uspsPattern = new string[]
    {
        "^(94|93|92|94|95)[0-9]{20}$",
        "^(94|93|92|94|95)[0-9]{22}$",
        "^(70|14|23|03)[0-9]{14}$",
        "^(M0|82)[0-9]{8}$",
        "^([A-Z]{2})[0-9]{9}([A-Z]{2})$"
    };

    string[] fedexPattern = new string[]
    {
        "^[0-9]{20}$",
        "^[0-9]{15}$",
        "^[0-9]{12}$",
        "^[0-9]{22}$"
    };

I use these in an eBay application I wrote:

USPS Domestic:

/^91[0-9]+$/

USPS International:

/^[A-Za-z]{2}[0-9]+US$/

FedEx:

/^[0-9]{15}$/

However, this might be eBay/Paypal specific, as all USPS Domestic labels start with "91". All USPS International labels start with two characters and end with "US". As far as I know, FedEx just uses 15 random digits.

(Please note that these regular expressions assume all spaces are removed. It would be fairly easy to allow for spaces though)

I believe FedEx is 12 digits:

^[0-9]{12}$

//UPS - UNITED PARCEL SERVICE final String UPS = "\b(1Z ?[0-9A-Z]{3} ?[0-9A-Z]{3} ?[0-9A-Z]{2} ?[0-9A-Z]{4} ?[0-9A-Z]{3} ?[0-9A-Z]|T\d{3} ?\d{4} ?\d{3})\b";

//USPS - UNITED STATES POSTAL SERVICE - FORMAT 1 final String USPS_FORMAT1 = "\b((420 ?\d{5} ?)?(91|92|93|94|01|03|04|70|23|13)\d{2} ?\d{4} ?\d{4} ?\d{4} ?\d{4}( ?\d{2,6})?)\b";

//USPS - UNITED STATES POSTAL SERVICE - FORMAT 2 final String USPS_FORMAT2 = "\b((M|P[A-Z]?|D[C-Z]|LK|E[A-C]|V[A-Z]|R[A-Z]|CP|CJ|LC|LJ) ?\d{3} ?\d{3} ?\d{3} ?[A-Z]?[A-Z]?)\b";

//USPS - UNITED STATES POSTAL SERVICE - FORMAT 3 final String USPS_FORMAT3 = "\b(82 ?\d{3} ?\d{3} ?\d{2})\b";

//FEDEX - FEDERAL EXPRESS final String FED_EX = "\b(((96\d\d|6\d)\d{3} ?\d{4}|96\d{2}|\d{4}) ?\d{4} ?\d{4}( ?\d{3})?)\b";

//ONTRAC final String ONTRAC = "\b(C\d{14})\b";

//DHL final String DHL = "\b(\d{4}[- ]?\d{4}[- ]?\d{2}|\d{3}[- ]?\d{8}|[A-Z{3}\d{7})\b";

    Sample tracking number 
    UPS        
    //"1Z 999 AA1 01 2345 6784"  
    Fed-ex
    // "449044304137821"
    USPS
    //"9400 1000 0000 0000 0000 00"

    final Pattern pattern = Pattern.compile(DHL, Pattern.CASE_INSENSITIVE | 
     Pattern.UNICODE_CASE);
    final Matcher matcher = pattern.matcher("1Z 999 AA1 01 2345 6784");

    if (matcher.find()) {
        System.out.println(true + "");
    }

It's working in java and android. https://regex101.com/ You can change your regex into another language regex by this link and generate code also.

Related