7 votes

Empêcher la chaîne de caractères répétée avec regex en PHP

Je cherche à créer une expression régulière en PHP qui vérifie qu'une chaîne est conforme aux règles suivantes :

  • Comporte de 1 à 7 occurrences de l'une des chaînes suivantes (Lun,Mar,Mer,Jeu,Ven,Sam,Dim)
  • Les chaînes sont séparées par une virgule
  • Non sensible à la casse
  • Aucune répétition de chaînes

Je pense avoir rempli les trois premiers aspects avec ce qui suit :

/^(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)(,(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)){0,6}$/i

J'ai du mal à empêcher les répétitions. Quelqu'un pourrait-il me conseiller ?

5voto

Martijn Points 5617

Est-ce que cela doit être une regex? Sinon :

$daysStart = 'Mon,Tues,Wed,mon';
$days = strtolower($daysStart);
$days = explode(",", $days); // séparation par virgule
$days = array_unique($days); // suppression des doublons
$days = implode(",", $days); // recollage avec des virgules

// Comparer la nouvelle chaîne à l'originale :
if(strtolower($days)===strtolower($daysStart )){ /*correspondance*/ }

Cela résulte en une chaîne en minuscules des jours, séparés par des virgules. Je ne suis pas sûr de ce que vous vouliez en sortie, vous pourriez vouloir sauvegarder l'entrée originale dans un autre fichier, ou ucfirst() les valeurs via un array_map() ou quelque chose, c'est juste pour vous montrer une autre méthode


Ou mon code plus court :

$daysStart = 'Mon,Tues,Wed,mon';
$days = explode(",", strtolower($daysStart ) );
$days = implode(",", array_unique($days) );
if(strtolower($days)===strtolower($daysStart )){ /*correspondance*/ }

ou fonction (en code court, peut être la version longue bien sûr) :

function checkDays($string){
    $days = explode(",", strtolower($string) );
    $days = implode(",", array_unique($days) );
    return (strtolower($days)===strtolower($daysStart)) ? true : false;// *
}

*J'aurais pu simplement faire le retour et les vérifications de chaîne, mais je préfère ajouter true/false d'une manière sûre pour être sûr que mon valeur de retour est toujours vraie ou fausse en tant que booléen, pas truthy ou falsy.

5voto

JonM Points 1182
^(Lun|Mar|Mer|Jeu|Ven|Sam|Dim)(?:,(?!\1|\2)(Lun|Mar|Mer|Jeu|Ven|Sam|Dim)){0,6}$

Vous pourriez utiliser ceci si les expressions régulières sont absolument nécessaires, mais je recommande plutôt la réponse de Martijn. Elle est beaucoup plus flexible et plus facile à lire.

Voici comment j'ai testé ceci en PHP :

Cela affiche :

0 Lun,Mon
0 Dim,Lun,Ven,Dim
1 Sam
1 Lun,Mer,Mar,Ven,Mer
1 Lun,Mar

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X