简体   繁体   中英

PHP regex prevent repeated string

Im trying to create a regular expression in PHP which is checking that a string conforms to the following rules:

  • Has 1 - 7 occurrences of one of the following strings (Mon,Tues,Wed,Thurs,Fri,Sat,Sun)
  • Strings separated by a ,
  • not case sensitive
  • No strings are repeated.

I believe I have fulfilled the first three aspects of this with the following:

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

I am struggling to get to grips with preventing any repeats. Can anyone advise?

Does it have to be a regex? If not:

$daysStart = 'Mon,Tues,Wed,mon';
$days = strtolower($daysStart);
$days = explode(",", $days); // split on comma
$days = array_unique($days); // remove uniques
$days = implode(",", $days); // join on comma

// Compare new string to original:
if(strtolower($days)===strtolower($daysStart )){ /*match*/ }

This results in a lowercase string of days, seperated by commas. Not sure what you wanted as output, you might want to save the original input in another far, or ucfirst() the values via an array_map() or something, this is just to show you another method


Or my code shorter:

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

or function (as short code, can be the longer version ofcourse):

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

*I could've done just the return and the str-checks, but I prefer to add true/false in a way im sure my returnvalue always is true of false as boolean, not truthy or falsy.

^(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)(?:,(?!\1|\2)(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)){0,6}$

You could use this if regex is an absolute requirement but I'd rather recommend Martijn's answer. It is much more flexible and easier to read.

Here is how i tested this in PHP:

<?php

$subject1 = "Mon,Mon";
$subject2 = "Sun,Mon,Fri,Sun";
$subject3 = "Sat";
$subject4 = "Mon,Wed,Tues,Fri,Wed";
$subject5 = "Mon,Tues";
$pattern = '/^(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)(?:,(?!\1|\2)(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)){0,6}$/i';
print_r(preg_match($pattern, $subject1, $matches) . " " . $subject1 . "\n");
print_r(preg_match($pattern, $subject2, $matches) . " " . $subject2 . "\n");
print_r(preg_match($pattern, $subject3, $matches) . " " . $subject3 . "\n");
print_r(preg_match($pattern, $subject4, $matches) . " " . $subject4 . "\n");
print_r(preg_match($pattern, $subject5, $matches) . " " . $subject5 . "\n");

?>

This outputs:

0 Mon,Mon
0 Sun,Mon,Fri,Sun
1 Sat
1 Mon,Wed,Tues,Fri,Wed
1 Mon,Tues

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM