Expressions régulières pour débutants : Comment se lancer dans la découverte de données sensibles

Toute solution de découverte et de classification des données s’appuie largement sur des expressions régulières (parfois appelées RegEx, expressions rationnelles ou motifs RegEx) pour identifier les données sensibles. Mais que sont les RegEx et comment les utiliser pour découvrir des données sensibles ? C’est l’objet de cet article.

Les expressions régulières sont un langage de programmation concis mais hautement spécialisé ; il s’agit essentiellement de caractères génériques survitaminés. Avec ce langage, vous pouvez spécifier des règles qui définissent les chaînes de caractères que vous recherchez. Par exemple, vous pouvez définir une RegEx qui trouve les adresses e-mail, les données personnelles identifiables, les informations médicales protégées ou les numéros de carte de crédit.

Les composants des RegEx

Une RegEx peut inclure des littéraux et des métacaractères.

Littéraux

Tout caractère individuel, à l’exception de ceux qui sont réservés comme métacaractères, est déjà une expression régulière en soi. Par exemple, www est une correspondance pour www.netwrix.com, alors que wwz n’en est pas une. Remarquez que les expressions régulières sont sensibles à la casse, www ne correspond donc pas à WWW ou wWw.

Métacaractères

Les caractères individuels suivants ne sont pas interprétés comme des littéraux mais ont une signification particulière :

  • . ^ $ * + ? { } [ ] \ | ( )

Le tableau suivant décrit le fonctionnement de chacun de ces métacaractères.

TypeMétacaractèreDescriptionExemples
Point.Le point représente n’importe quel caractère.net.rix correspond aussi bien à www.netwrix.com qu’à www.netfrix.com.
Classe de caractère[]Établit une correspondance avec tout ce qui se trouve à l’intérieur des crochets.
Le caractère ^ désigne une exception. Inséré dans une classe, le caractère ^ indique une exception pour la recherche. Par exemple, [^n] correspond à tout caractère, sauf n.
Remarquez que les métacaractères (à cette exception près) ne sont pas actifs dans les classes. Par exemple,[net$] correspond à n’importe lequel des caractères n, e, t ou $ ($ est un métacaractère, mais dans une classe de caractères, il ne correspond qu’à $).
Le caractère ^ désigne une exception. Inséré dans une classe, le caractère ^ indique une exception pour la recherche. Par exemple, [^n] correspond à tout caractère, sauf n.
Vous pouvez indiquer des suites de caractères individuels. Par exemple, net[wrx] correspond à netw, netr et netx, mais pas à netz.
Vous pouvez également rechercher une plage de caractères en indiquant deux caractères séparés par un trait d’union ; par exemple, net[a-z] correspond à neta, netw et netf, mais pas à net1.
Ancres^Établit une correspondance avec des caractères au début d’une chaîne de caractères^https correspond à https://netwrix.com, mais pas à www.netwrix.com ni à http://netwrix.com
$Établit une correspondance avec des caractères à la fin d’une chaîne de caractèrescom$ correspond à www.netwrix.com ou à télécom, mais pas à communication.
Itérations / quantificateurs?Établit une correspondance si le caractère qui le précède est présent une fois ou absent. Il est utile pour trouver des caractères optionnels.Coleu?r correspond à la fois à couleur et à couler.
*Trouve une correspondance si le caractère qui le précède est présent une ou plusieurs fois, ou absent. Il est utile pour trouver des séries optionnelles de caractères.ne*t correspond à nt, net , neeet, etc.
+Trouve une correspondance si le caractère qui le précède est présent une ou plusieurs fois.
Remarquez la différence entre * et +. * recherche zéro occurrence ou plus du caractère précédent ; + recherche au moins une occurrence.
ne+t correspond à net et neeet, mais pas à nt.
|L’opérateur de choix cherche une correspondance avec l’expression qui le précède OU celle qui le suit.net|wrix correspond à net et à wrix.
{}{x} trouve une correspondance si l’élément qui précède a exactement x occurrences.
{x,y} trouve une correspondance si l’élément qui précède est trouvé au moins x fois et pas plus de y fois.
n{3} correspond à nnn, nnnn et nnnd (qui incluent tous n trois fois de suite), mais ne correspond pas à nnw.
9{3} correspond à 999, 1234999124 et text999text, mais pas à 84299238, 9909 ni page992.
n{3,5} correspond à nnn, nnnn et nnnnn.
Regroupement et capture()Définit une sous-expression qui peut être rappelée ultérieurement par une abréviation : La première sous-expression entre parenthèses peut être rappelée par \1, la seconde par \2 et ainsi de suite.
Les parenthèses s’utilisent normalement soit avec | (opérateur de choix) à l’intérieur, soit avec des quantificateurs à l’extérieur.
Gr(i|o)s correspond à Gris et à Gros.
[0-9]([-])[0-9]\1[0-9] correspond à 3-4-2 et 4-6-1, mais pas à 1-23, 42-1 ni 234.
Séquence d’échappement\Le métacaractère qui suit la barre oblique inversée est utilisé comme un littéral.
Remarquez que certaines séquences commençant par \ ne sont pas des séquences d’échappement. Elles représentent en fait des ensembles prédéfinis de caractères qui sont souvent utiles, comme l’ensemble des chiffres, l’ensemble des lettres ou l’ensemble des caractères qui ne sont pas des espaces. Les plus courantes sont mentionnées ci-dessous en tant que « métacaractères spéciaux ».
www\.netwrix\.com correspond à www.netwrix.com, mais pas à www,netwrix,com.
Métacaractères spéciaux\sCorrespond à tout caractère d’espacement (espace, tabulation, saut de ligne ou saut de page).Netwrix\sAuditor correspond à Netwrix Auditor et à Netwrix(tab)Auditor, mais pas à Netwrix<5 espaces>Auditor ni à NetwrixAuditor.
\SCorrespond à tous les caractères qui ne sont pas des caractères d’espacement.\Snetwrix correspond à Xnetwrix et à 1netwrix.
\wCorrespond à n’importe quel caractère alphanumérique.\w\w\w correspond à net, dfw et Netwrix.
\WCorrespond à n’importe quel caractère non alphanumérique.netwrix\W correspond à netwrix! et netwrix?.
\dCorrespond à tout chiffre.Netwrix\d\d correspond à Netwrix80 et Netwrix90.
\DCorrespond à tout caractère qui n’est pas un chiffre.Netwrix\D correspond à Netwrix) et Netwrix-.
\aCorrespond à tout caractère alphabétique, majuscule ou minuscule.net\arix correspond à netWrix, netfrix et netarix.
\bDéfinit une limite de mot.\brix correspond à rix et à rixon, mais pas à netwrix.
\BDéfinit une non-limite de mot.\Brix correspond à Netwrix et à trix, mais pas à rixon.

Combinaisons de métacaractères

Nous connaissons maintenant presque tous les métacaractères et nous sommes prêts à les combiner.

Exemple : recherche de numéros de plaque d’immatriculation

Supposons que nous devions trouver un numéro de plaque d’immatriculation au format aaa-nnnn – les trois premiers caractères doivent être alphanumériques et les quatre derniers doivent être numériques. Le trait d’union peut être remplacé par n’importe quel caractère ou même disparaître.

La RegEx qui convient est :

  • \b[0-9A-Z]{3}([^ 0-9A-Z]|\s)?[0-9]{4}\b

Examinons-la de plus près :

  • \b spécifie une limite de mot, les chaînes de caractères correspondantes ne peuvent donc pas faire partie d’une chaîne plus grande.
  • [0-9A-Z]{3} signifie que les trois premiers caractères doivent être alphanumériques.
  • ([^ 0-9A-Z]|\s)? signifie que la partie suivante de la chaîne de caractères doit être soit un délimiteur (un caractère non alphanumérique ou un espace), soit rien du tout.
  • [0-9]{4} signifie que la partie suivante de la chaîne doit être composée de 4 chiffres.
  • \b spécifie une autre limite de mot.

Cette RegEx correspond aux numéros de plaque suivants : NT5-6345, GH3 9452, XS83289

Mais elle ne correspond pas aux numéros suivants : ZNT49371, HG3-29347, nt4-9371

Exemple : recherche de numéros de sécurité sociale

Prenons l’exemple des numéros de sécurité sociale américains (SSN), qui prennent toujours la forme nnn-nn-nnnn.

La RegEx la plus simple pour cette recherche est la suivante :

  • [0-9]{3}-[0-9]{2}-[0-9]{4}

Cependant, elle générera des faux positifs, car tous les numéros qui ont ce format ne sont pas des SSN existants. De plus, elle manquera des SSN existants, notamment ceux qui sont écrits sans traits d’union. Pour obtenir des résultats plus précis, nous devons en élaborer une plus complexe. Nous savons que :

  • Aucun des trois « blocs » de chiffres ne peut contenir que des zéros.
  • Le premier bloc ne peut pas être 666, ni compris entre 900 et 999 inclus.
  • Les SSN peuvent être écrits avec des espaces au lieu des traits d’union, ou sans aucun délimiteur.
  • Si le premier bloc commence par un 7, il doit être suivi d’un nombre compris entre 0 et 6, puis d’un troisième chiffre quel qu’il soit.

Par conséquent, la RegEx avancée ressemblera à ceci :

  • \b(?!000|666|9\d{2})([0-8]\d{2}|7([0-6]\d))([-]?|\s{1})(?!00)\d\d\2(?!0000)\d{4}\b

Comme précédemment, les \b au début et à la fin spécifient les limites de la chaîne. Examinons plus en détail chaque bloc de chiffres entre ces deux limites.

Premier bloc

  • (?!000|666|9\d{2}) est une anticipation négative qui spécifie que le nombre ne doit pas commencer par 000, 666 ou 9 suivi de deux chiffres.
  • ([0-8]\d{2} spécifie que la chaîne doit commencer par un chiffre compris entre 0 et 8 et qu’elle doit être suivie de deux autres chiffres (de 0 à 9).
  • |7[0-6]\d)) indique que si la chaîne commence par 7, le chiffre suivant doit être compris entre 0 et 6, et suivi d’un chiffre quelconque.
  • ([-]?|\s{1}) spécifie qu’après les trois chiffres, il doit y avoir un trait d’union, un espace ou rien du tout, pour marquer la fin du premier bloc.

Deuxième bloc

  •  (?!00) est une autre anticipation négative qui spécifie qu’il ne doit pas y avoir de double zéro dans le deuxième bloc.
  • \d\d spécifie que le deuxième bloc doit être composé de deux chiffres, quels qu’ils soient.
  • \2 correspond au même texte que le second groupe de capture : ([-]?|\s{1}). Ce rappel spécifie que le deuxième bloc peut se terminer par un trait d’union, un espace ou aucun caractère du tout.

Troisième bloc

  • (?!0000) est une autre anticipation négative qui spécifie qu’il ne doit pas y avoir de quadruple zéro dans le troisième bloc.
  • \d{4} requiert quatre chiffres dans le troisième bloc du SSN.

Exemples de RegEx couramment utilisées

Pour trouverUtilisez cette RegExExemple de correspondance
Adresses e-mail^[\w\.=-]+@[\w\.-]+\.[\w]{2,3}$T.Simpson@netwrix.com
Numéros de sécurité sociale américains\b(?!000|666|9\d{2})([0-8]\d{2}|7([0-6]\d))([-]?|\s{1})(?!00)\d\d\2(?!0000)\d{4}\b513-84-7329
Adresses IPV4^\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}$192.168.1.1
Dates au format MM/JJ/AAAA^([1][12]|[0]?[1-9])[\/-]([3][01]|[12]\d|[0]?[1-9])[\/-](\d{4}|\d{2})$05/05/2018
Numéros de cartes Mastercard^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$5258704108753590
Numéros de cartes Visa\b([4]\d{3}[\s]\d{4}[\s]\d{4}[\s]\d{4}|[4]\d{3}[-]\d{4}[-]\d{4}[-
]\d{4}|[4]\d{3}[.]\d{4}[.]\d{4}[.]\d{4}|[4]\d{3}\d{4}\d{4}\d{4})\b
4563-7568-5698-4587
Numéros de cartes American Express^3[47][0-9]{13}$34583547858682157
Codes ZIP US^((\d{5}-\d{4})|(\d{5})|([A-Z]\d[A-Z]\s\d[A-Z]\d))$97589
Chemins d’accès à des fichiers\\[^\\]+$\\fs1\shared
URL(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+
|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
www.netwrix.com

Ressources Web utiles concernant les RegEx

  • https://regexr.com et https://regex101.com vous permettent de vérifier vos RegEx grâce à une mise en surbrillance de la syntaxe et à des infobulles.
  • https://regexcrossword.com est un jeu de mots croisés dans lequel les définitions utilisent des expressions régulières.
  • https://www.regular-expressions.info est un excellent site d’information sur les expressions régulières. L’utilitaire Notepad++ dispose également d’une extension d’aide RegEx qui vous sera très utile lorsque vous travaillez avec les expressions régulières.