Validation par motifs

Nettoyer des données en Java

Dennis Lee

Software Engineer

Pourquoi valider les motifs

  • Les données doivent suivre des formats précis pour être fiables
  • Exemple : les dates doivent suivre un format cohérent comme d-MMM-yy
  • Problème : formats de date incohérents comme « 24/02/22 »
  • Solution : utiliser la validation par motifs pour repérer les formats incohérents

 

// Nous avons extrait ces dates de notre jeu de données
List<String> dates = Arrays.asList("4-Jan-22", "1-Aug-22", "7-Jul-22", 
                                   "27-Apr-22", "24/02/22");
Nettoyer des données en Java

Trois types de validation par motifs

  • Correspondance complète
    • À utiliser quand le format doit être exact
    • Exemple : valider des dates au format d-MMM-yy
  • Recherche de motif
    • À utiliser quand la position exacte n’importe pas
    • Exemple : trouver/vérifier des catégories produit dans des descriptions
    • Produits avec « Dark Chocolate » : « 85% Dark Chocolate Bar », « Dark Chocolate with Nuts »
  • Correspondance de caractères
    • À utiliser pour un contrôle rapide des données
    • Exemple : vérifier si un champ quantité contient des lettres (« 12.5x »)
Nettoyer des données en Java

Définir des motifs avec des regex

  • Faire correspondre le motif d-MMM-yy (comme « 4-Jan-22 »)
  • Regex : \\d{1,2}-[A-Za-z]{3}-\\d{2}

 

\\d{1,2}     // 1 à 2 chiffres pour le jour (4 ou 27)
-            // tiret littéral

[A-Za-z]{3} // exactement 3 lettres pour le mois, p. ex. Jan ; casse indifférente - // tiret littéral
\\d{2} // exactement 2 chiffres pour l’année (p. ex. 22)
Nettoyer des données en Java

Correspondance complète

import java.util.regex.Pattern;
// Faire correspondre d-MMM-yy
Pattern datePattern = Pattern.compile("\\d{1,2}-[A-Za-z]{3}-\\d{2}");

for (String date : dates) { // Vérifier si la date correspond à datePattern boolean isValid = datePattern.matcher(date).matches(); System.out.println(date + " est valide : " + isValid); }
Nettoyer des données en Java

Correspondance complète : sorties

4-Jan-22 est valide : true
1-Aug-22 est valide : true
7-Jul-22 est valide : true
27-Apr-22 est valide : true
24/02/22 est valide : false
Nettoyer des données en Java

Recherche de motif

import java.util.regex.Matcher;
Pattern monthPattern = Pattern.compile("[A-Za-z]{3}"); // 3 lettres comme "Jan"

for (String date : dates) { Matcher matcher = monthPattern.matcher(date); // monthPattern est-il dans date ?
if (matcher.find()) { // Renvoie true si le motif est trouvé
// matcher.group() renvoie le contenu correspondant System.out.println("Mois trouvé : " + matcher.group()); } else { System.out.println("Aucun mois trouvé dans : " + date); } }
Nettoyer des données en Java

Recherche de motif : sorties

Mois trouvé : Jan
Mois trouvé : Aug
Mois trouvé : Jul
Mois trouvé : Apr
Aucun mois trouvé dans : 24/02/22
Nettoyer des données en Java

Correspondance de caractères

import com.google.common.base.CharMatcher;
for (String date : dates) {
    boolean isValid =
            // Vérifier la présence de chiffres
            CharMatcher.inRange('0', '9').matchesAnyOf(date) &&

// Vérifier la présence de lettres (majuscules et minuscules) CharMatcher.inRange('a', 'z') .or(CharMatcher.inRange('A', 'Z')).matchesAnyOf(date) &&
CharMatcher.is('-').matchesAnyOf(date); // Vérifier les tirets System.out.println(date + " contient des caractères valides : " + isValid); }
Nettoyer des données en Java

Correspondance de caractères : sorties

4-Jan-22 contient des caractères valides : true
1-Aug-22 contient des caractères valides : true
7-Jul-22 contient des caractères valides : true
27-Apr-22 contient des caractères valides : true
24/02/22 contient des caractères valides : false
Nettoyer des données en Java

Récapitulatif

// Définir le motif d-MMM-yy, comme 4-Jan-22
Pattern datePattern = Pattern.compile("\\d{1,2}-[A-Za-z]{3}-\\d{2}");
// Correspondance complète (date correspond-elle à datePattern ?)
boolean matchesPattern = datePattern.matcher(date).matches();
// Recherche de motif (la date contient-elle un mois en sous-chaîne ?)
boolean hasMonth = Pattern.compile("[A-Za-z]{3}").matcher(date).find();
// Correspondance de caractères (la date contient-elle des chiffres ?)
boolean hasDigits = CharMatcher.digit().matchesAnyOf(date);
Nettoyer des données en Java

Passons à la pratique !

Nettoyer des données en Java

Preparing Video For Download...