PHP正则表达式防止重复字符串

PHP正则表达式防止重复字符串,php,regex,Php,Regex,我试图在PHP中创建一个正则表达式,该表达式正在检查字符串是否符合以下规则: 以下字符串之一出现1-7次(周一、周二、周三、周四、周五、周六、周日) 字符串之间用 不区分大小写 没有重复的字符串 我相信我已经完成了这项工作的前三个方面: /^(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)(,(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)){0,6}$/i 我正在努力防止任何重复。有人可以建议吗?它必须是正则表达式吗?如果没有: $daysStart =

我试图在PHP中创建一个正则表达式,该表达式正在检查字符串是否符合以下规则:

  • 以下字符串之一出现1-7次(周一、周二、周三、周四、周五、周六、周日)
  • 字符串之间用
  • 不区分大小写
  • 没有重复的字符串
我相信我已经完成了这项工作的前三个方面:

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

我正在努力防止任何重复。有人可以建议吗?

它必须是正则表达式吗?如果没有:

$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*/ }
这将产生一个小写的天数字符串,以逗号分隔。不确定您想要什么作为输出,您可能希望将原始输入保存在另一个far中,或者通过
数组映射()将值保存在
ucfirst()
中,这只是为了向您展示另一种方法


或者我的代码更短:

$daysStart = 'Mon,Tues,Wed,mon';
$days = explode(",", strtolower($daysStart ) );
$days = implode(",", array_unique($days) );
if(strtolower($days)===strtolower($daysStart )){ /*match*/ }
或函数(作为短代码,当然可以是较长的版本):

*我本可以只做返回和str检查,但我更喜欢添加true/false,因为我确信我的返回值总是true或false作为布尔值,而不是truthy或falsy

^(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)(?:,(?!\1|\2)(Mon|Tues|Wed|Thurs|Fri|Sat|Sun)){0,6}$
如果正则表达式是一个绝对的要求,你可以使用它,但我更愿意推荐Martijn的答案。它更灵活,更容易阅读

下面是我如何在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");

?>

而且可能对复制品有所帮助。你可能需要两个过程——使用正则表达式匹配重复项要比不匹配重复项容易。我相信输出应该是真/假的。我喜欢在线,csv是一个很好的界面,尽管它只限于逗号,其中explode有点灵活感谢输入。我已经用preg_match测试过了,它仍然匹配“Mon,Mon”,在使用这个测试工具时,它似乎按照建议工作……抱歉,仍然有点困惑。我可以看到它在你链接的赛前测试中起作用。我将确切的正则表达式复制到php中,在那里使用preg_match,结果是matchpreg_match()将返回零而不是false。这表明字符串没有满足您的要求。不用担心!我对使用不一致的引语感到非常内疚(正如你可能从我的回答中看到的)。这让我的一些同事发疯,但我正在努力变得更好。这个答案解释了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");

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