7

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?

1
  • 1
    This question and this one might help with the duplicates. You might need two passes -- it's easier to use a regex to match duplicates than to match no duplicates. Commented Sep 17, 2013 at 14:14

2 Answers 2

5
^(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
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the input. I have tested this using preg_match and it still matches "Mon,Mon"
preg_match test It seems to work as proposed when using this testing tool...
Sorry still slightly confused. I can see it works on preg_match test you've linked to. I copy the exact regex into php, use preg_match there and it comes up as a match
preg_match() will return zero instead of false. This is the indication that the string hasn't met your requirements.
No worries! I am very guilty of using inconsistent quotes (as you can probably see from my answer). It drives some of my co workers crazy but I am trying to get better. This answer explains the effect of different quotes in PHP stackoverflow.com/questions/3446216/…
|
5

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.

2 Comments

I believe the output is supposed to be true/false
I like the onliner, and the csv is a nice touch, though it limits to commas, where explode is a bit more flexible

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.