Regex ATC code (medicine)
The WHO ATC classification (Oslo collaborating centre) has five levels: an anatomical group (14 letters: A B C D G H J L M N P R S V), a therapeutic subgroup (2 digits), pharmacological (1 letter), chemical (1 letter) and the substance (2 digits), e.g. 'A10BA02' for metformin. The attempts I read don't follow that list: bioregistry and identifiers.org accept any letter and any number of digits, Wikidata's format expression requires a final digit and accepts up to 'V', Wikidata's constraint one is correct but unanchored. Here's a pattern limiting the first character to the 14 groups and accepting levels 1, 2, 3, 4 and 5, compared against those attempts.
/^[ABCDGHJLMNPRSV](?:[0-9]{2}(?:[A-Z](?:[A-Z](?:[0-9]{2})?)?)?)?$/passes 36/36 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| bioregistry / identifiers.org — n'importe quelle lettre initiale et n'importe quel nombre de chiffres : « E10BA02 », « A1 » et « A10BA2 » passent | ^[A-Z](\d+([A-Z]{1,2}(\d+)?)?)?$ | 26 / 36 | safe |
| Wikidata P267 (format de la propriété) — chiffre final obligatoire, lettres initiales A-V (E, F, I… acceptés), jamais « A10BA » (4e niveau) seul, non ancrée | [A-V]([0-9][0-9]([A-Z]([A-Z]([0-9][0-9])?)?)?)[0-9] | 20 / 36 | safe |
| Wikidata P267 (contrainte de format) — bonne liste de lettres et bons niveaux, mais sans ancres : « xA10BA02x » passe | [ABCDGHJLMNPRSV]([0-9][0-9]([A-Z]([A-Z]([0-9][0-9])?)?)?)? | 21 / 36 | safe |
Implementation
const re = new RegExp("^[ABCDGHJLMNPRSV](?:[0-9]{2}(?:[A-Z](?:[A-Z](?:[0-9]{2})?)?)?)?$", "");
re.test(input);Limits
- Valide seulement la FORME : un code correct du point de vue des lettres et des chiffres peut ne pas exister dans l'index de l'OMS (« A99ZZ99 » passe). L'existence se vérifie dans l'ATC/DDD Index, mis à jour chaque année.
- Codes vétérinaires ATCvet (préfixe Q, par exemple QA07AA90) refusés : ils relèvent d'un autre index. Les niveaux 2, 3 et 4 sont acceptés (« N02 », « N02B », « N02BE ») ; la longueur de 2 ou 6 caractères est refusée.
- Ne dit rien des codes de combinaison ni des doses (DDD) ; les codes d'un même principe actif peuvent changer d'une année à l'autre.