Python RegEx for all National Drug Codes (NDC 10 & 11) formats

640 views Asked by At

Goal: RegEx to fit many posible NDC 10 & 11 formats.

I've made a great start... NDC 10:

^[0-9][0-9][0-9][0-9]\-[0-9][0-9][0-9][0-9]\-[0-9][0-9]$

e.g. 1234-1234-12 Reference


However, I've since learnt there are other formats and 11 digits:

  • 4-4-2
  • 5-3-2
  • 5-4-1
  • 5-4-2 (11 digits)

How can I write one RegEx for all these possibilities?

Issues:

  1. Optional 11th digit,
  2. Moving hyphen
2

There are 2 answers

0
Wiktor Stribiżew On BEST ANSWER

You can use

^(?:\d{4}-\d{4}-\d{2}|\d{5}-(?:\d{3}-\d{2}|\d{4}-\d{1,2}))$

See the regex demo. Details:

  • ^ - start of string
  • (?: - start of the first non-capturing group:
    • \d{4}-\d{4}-\d{2} - four digits, -, four digits, -, two digits
    • | - or
    • \d{5}- - five digits, -
    • (?: - start of the second non-capturing group:
      • \d{3}-\d{2} - three digits, -, two digits
      • | - or
      • \d{4}-\d{1,2} - four digits, - and one or two digits
    • ) - end of the second non-capturing group
  • ) - end of the first non-capturing group.
  • $ - end of string.
0
Sean O'Malley On

A way to do this within pandas DataFrame using lists parsing:

# add zeros to each portion of ndc10 to fit 5,4,2 ndc11 0-filled format
a = [f"0{x[0]}" if len(x[0]) == 4 else x[0] for x in list(ndcd.NDC10.str.split("-"))]
b = [f"0{x[1]}" if len(x[1]) == 3 else x[1] for x in list(ndcd.NDC10.str.split("-"))]
c = [f"0{x[2]}" if len(x[2]) == 1 else x[2] for x in list(ndcd.NDC10.str.split("-"))]

# rejoin sections to full ndc11
ndcd["NDC11"] = ["".join(x) for x in list(zip(a, b, c))]