我有一个约会(例如yyyy-mm-dd hh:mm:ss)我希望能够返回true如果我们有一个字符串匹配该模式,完全或部分匹配该模式,从头开始结束例如。 44
会匹配该模式,因为-12
会匹配yy,但-
不匹配,因为preg_match
不是有效的“y”字符。
我发现了一些不优雅的解决方案。我可以对#^\d(\d(\d(\d(-)?)?)?)?$#
做类似的事情:
$patterns = [
'',
'\d',
'\d\d',
'\d\d\d',
'\d\d\d\d',
'\d\d\d\d-',
...
];
isset($patterns[strlen($str)] && preg_match('#^' . $patterns[strlen($str)] . '$#', $str)
根据年份执行部分匹配。它需要扩展到占月,日,小时,分钟等,但这应该显示想法#1。
我也可以做点像......
switch (strlen($str)) {
case 1: return preg_match('#^\d$#', $str);
case 2: return preg_match('#^\d\d$#', $str);
case 3: return preg_match('#^\d\d\d$#', $str);
case 4: return preg_match('#^\d\d\d\d$#', $str);
case 5: return preg_match('#^\d\d\d\d-$#', $str);
...
}
但这种情况似乎也很复杂。
我也可以这样做:
2005-
但这似乎也很臃肿。
换句话说,我正在寻找2
将返回true的函数,2005-1
和-2005
也是如此。但205-
将返回false,neubert
或WHERE date_column LIKE '$str%'
也会返回。
我希望能够将有效值传递给SQL查询。例如。 date_column
。如果-12-
是DATETIME,则搜索date_column
会浪费时间,因为<head>
无法将其作为值。
有什么想法吗?
答案 0 :(得分:2)
根据您的问题下方的评论,如果我理解正确的问题,您可以使用此单一正则表达式来匹配您的输入:
^(?:\d{1,3}|\d{4}(?:-(?:\d{1,2}(?:-\d{0,2})?)?)?)$
答案 1 :(得分:2)
这样的事情应该有效:
function doesMatch($str) {
// The date pattern split so that each array entry matches exactly one character
$pattern_chunks = array(
'\d', '\d', '\d', '\d', '-',
'\d', '\d', '-',
'\d', '\d',
'\s',
'\d', '\d', ':',
'\d', '\d', ':',
'\d', '\d'
);
$chunk_count = count($pattern_chunks);
$str_len = strlen($str);
// If the string is empty, it's clearly not a date
if ( $str_len < 1 ) { return false; }
// If the string is longer than our pattern chunks, there's no way it matches
if ( $str_len > $chunk_count ) { return false; }
// Make a pattern using the first N chunks of our pattern parts
$pattern = '^' . implode('', array_slice($pattern_chunks, 0, $str_len)) . '$';
// Return if the string matches
return (preg_match($pattern, $str) > 0);
}
例如,您的输入字符串长度为6个字符,它仅使用日期模式的前6个块(^\d\d\d\d-\d$
)。
答案 2 :(得分:1)
我知道这个问题已经得到解决和关闭,但我认为这是一个有趣的挑战,我决心提出一个非正则表达式解决方案。我还希望它更具可重用性,而不是针对一个特定情况进行硬编码。
这是我最终的结果;我相信它可以进一步改进! :)
// case-insensitive string format comparison
// if $strict is true, the string lengths must also match
// if $strict is false, the strings are compared left to right
function strfcasecmp($str, $format, $strict = false) {
$len1 = strlen($str);
$len2 = strlen($format);
// make sure we have a valid length
if ($len1 < 1 || $len1 > $len2) {
return false;
}
// if strict, make sure length matches as well
if ($strict) {
if ($len1 !== $len2) {
return false;
}
}
// compare alpha, numeric, space & printable characters
for ($i = 0; $i < $len1; $i++) {
switch (true) {
case ctype_alpha($format[$i]):
if (!ctype_alpha($str[$i])) {
return false;
}
break;
case ctype_digit($format[$i]):
if (!ctype_digit($str[$i])) {
return false;
}
break;
case ctype_space($format[$i]):
if (!ctype_space($str[$i])) {
return false;
}
break;
case ctype_punct($format[$i]):
if ($str[$i] !== $format[$i]) {
return false;
}
break;
default:
// character must match at least one type specified above
return false;
}
}
return true;
}
基于原始问题的使用示例:
$format = '0000-00-00 00:00:00';
var_dump(strfcasecmp('44', $format)); // true
var_dump(strfcasecmp('-12', $format)); // false
var_dump(strfcasecmp('2005-', $format)); // true
var_dump(strfcasecmp('2', $format)); // true
var_dump(strfcasecmp('2005-1', $format)); // true
var_dump(strfcasecmp('-2005', $format)); // false
var_dump(strfcasecmp('205-', $format)); // false
var_dump(strfcasecmp('neubert', $format)); // false
答案 3 :(得分:0)
您也可以使用strpos()
匹配:
$a = "2016-05-17 was a good day.";
if (strpos(substr($a, 0, 10), '2016-05-17') !== false) {
echo "Indeed it was";
}