Rexact
Cheatsheet

Regex Polish PESEL

A PESEL has 11 digits: YYMMDD, 4 serial digits and a check digit. A subtlety rarely respected: the month encodes the century by an offset (+80 for 1800-1899, +20 for 2000-2099, +40 for 2100-2199, +60 for 2200-2299), so valid months are 01-12, 21-32, 41-52, 61-72 and 81-92. Microsoft's Presidio PII library has the right alternation but does not anchor the pattern, so a 12- or 13-digit number containing a PESEL passes. validator.js settles for '10 or 11 digits', month 13 included. Here's an anchored pattern bounding the month by century and the day from 01 to 31, compared against those attempts.

/^[0-9]{2}(?:[02468][1-9]|[13579][012])(?:0[1-9]|[12][0-9]|3[01])[0-9]{5}$/
passes 24/24 cases

Comparison of existing patterns

Implementation

const re = new RegExp("^[0-9]{2}(?:[02468][1-9]|[13579][012])(?:0[1-9]|[12][0-9]|3[01])[0-9]{5}$", "");
re.test(input);

Limits

  • Valide seulement la FORME : ne calcule pas la clé (poids 1-3-7-9). « 44051401358 » et « 02070803629 » ont la bonne forme mais une clé fausse, et passent ce motif. Ne valide pas non plus le jour dans le mois : « 02223013623 » (30 février 2002) passe, tout comme un 29 février d'une année non bissextile.
  • Ne vérifie pas la cohérence du sexe (le dernier chiffre de la série est pair pour une femme, impair pour un homme) ni l'existence réelle du numéro : seul le registre PESEL le confirme. N'utilisez jamais de vrais PESEL dans vos tests ; les exemples ici viennent de documents officiels et de suites de tests.
  • À cause du décalage de siècle, tester simplement « mois ≤ 12 » rejetterait tous les PESEL des personnes nées depuis 2000 (mois 21 à 32). Ce motif accepte ces mois, ainsi que ceux des siècles 1800, 2100 et 2200.
  • Accepte 11 chiffres collés, sans espace ni tiret : « 02 070 803628 » est rejeté, normalisez la saisie avant validation.

Related pages