简体   繁体   English

更正正则表达式以匹配日期

[英]Correct Regular expressions to match a date

What is the correct regular expression to use to validate a date like. 用于验证日期的正确正则表达式是什么? 2009-10-22 or 2009-01-01 etc. Platform PHP 2009-10-22或2009-01-01等。平台PHP

This (from regexplib.com ) will match what you want, and perform checks for leap years, days-per-month etc. It's a little more tolerant of separators than you want, but that can be easily fixed. (来自regexplib.com )将匹配您想要的内容,并执行leap年,每月天数等检查。分隔符的容忍度超出了您的期望,但可以轻松地解决。 As you can see, it's rather hideous. 如您所见,这非常可怕。

Alternatively (and preferably in my opinion) you may want to simply check for figures in the correct places, and then perform leap year and days-per-month checks in code. 另外(最好是我认为),您可能希望简单地检查正确位置的数字,然后在代码中执行leap年和每月的天数检查。 Sometimes one regexp isn't so understandable and there's greater clarity in performing the checks in code explicitly (since you can report precisely what's wrong - "only 30 days in November", rather than a "doesn't match pattern" message, which is next to useless) 有时,一个正则表达式不是那么容易理解,并且在代码中显式执行检查会更加清晰(因为您可以准确地报告出了什么问题-“ 11月仅30天”,而不是“不匹配模式”消息,旁边没用)

If you want something simple that does a little more than just validates format, but doesn't go as far as validating how many days is in the month that is entered, or leap years, you can use this: 如果您想做一些简单的事情,其功能不只是验证格式,还不能验证输入的月份或leap年中的多少天,则可以使用以下方法:

^(19|20)[0-9]{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$

This example allows years 19xx and 20xx 此示例允许年份为19xx和20xx

As you have to deal with accepting 2009-02-28 but not 2009-02-29 but accept 2008-02-28 you need more logic that 1 think a regex can give. 因为您必须处理接受2009-02-28而不是2009-02-29而是接受2008-02-28,所以您需要1认为正则表达式可以给出的更多逻辑。 (But if someone can show it I would be impressed) (但如果有人可以证明这一点,我会印象深刻)

I would try to convert it to a date and report if the conversion failed or if you you language has a check date function use that. 我会尝试将其转换为日期并报告转换是否失败,或者您使用的语言是否具有检查日期功能。

\\d{4}-\\d{2}-\\d{2} would match string in that form, but to check if date is valid, you'd had to break that string to year, month and date (you can use this regexp for that) parts and check each of them. \\d{4}-\\d{2}-\\d{2}会匹配该格式的字符串,但是要检查日期是否有效,您必须将该字符串分解为年,月和日(可以使用该正则表达式)部分,并检查每个部分。

You can additionally, make sure that year must start with 1 or 2: [12]\\d{3}-\\d{2}-\\d{2} , and you can also do the same for month and day: [12]\\d{3}-[01]\\d-[0123]\\d (but I would go with the first regexp and compare parts "manually") 您还可以确保年份必须以1或2开头: [12]\\d{3}-\\d{2}-\\d{2} ,并且您也可以对月份和日期进行同样的操作: [12]\\d{3}-[01]\\d-[0123]\\d (但我会使用第一个正则表达式并“手动”比较部分)

在1900年至2000年之间的日期中,在网络上发现了此日期并对其进行了测试,并显示了稳定的日期:

(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])

OK, a regex that will validate month and day ranges could be 好的,可以验证月份和日期范围的正则表达式可能是

[0-9]{4}-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])

If you want to restrict the years, say, from 1900 to 2050, you could end up with 如果您想限制年份,例如从1900年到2050年,您可能会得到

(?:2050|20[0-4][0-9]|19[0-9]{2})-(?:1[0-2]|[1-9])-(?:3[01]|[12][0-9]|[1-9])

They will not catch "subtly wrong" dates like February 31st, so it's really quite clear that a sanity check needs to be performed outside of the regex. 他们不会赶上2月31日这样的“非常错误”的日期,因此,非常清楚的是,需要在正则表达式之外执行健全性检查。

在.NET正则表达式中:

\d{4}\-\d{2}\-\d{2}
[0-9]{4}-[0-9]{2}-[0-9]{2}

or 要么

\d\d\d\d-\d\d-\d\d

or 要么

... ...

simply read first regex tutorial 只需阅读第一个regex教程

 ^\d{4}-\d{2}-\d{2}$

但没有正则表达式可以阻止某人输入“ 9867-39-56”

For a complete validation (which would include verifying that the day, month and year parts are valid) a Regex is not the tool of choice. 对于完整的验证(其中包括验证日期,月份和年份部分是否有效),Regex不是首选工具。 Apart from month issues you'd get into trouble with leap years... 除了月份问题之外,您还会遇到leap年的麻烦...

So, if you just want to check if the rough format is correct, or isolate the different parts (year-month-day), a regex is fine. 因此,如果您只想检查粗略格式是否正确,或者隔离不同的部分(年月日),则可以使用正则表达式。

([0-9]{1,4})-(1[012]|0?[1-9])-([12][0-9]|3[01]|0?[1-9])

This is already pretty exact and captures the year (0..9999), month and day into capture groups, ready for parsing... 这已经很精确了,可以将年(0..9999),月和日捕获到捕获组中,以供分析...

If you can rely on more than a regular expression, an hybrid solution by using Posix functions date() and time() delivered with PHP could look like this: 如果您不仅可以依赖正则表达式,那么使用PHP附带的Posix函数date()和time()的混合解决方案可能如下所示:

<?php
date_default_timezone_set("GMT");

function validateDate($date)
{
    if (preg_match("^[0-9]{4}-[0-9]{2}-[0-9]{2}^", $date))
    {
        return date('Y-m-d', strtotime($date)) === $date;
    }
    return false;
}

// Some tests
$dates = array(
    '2009-09-09', '2009-09-32', '2009-31-00', '2035-01-02',
);
foreach($dates AS $date)
{
    echo $date .': '. (validateDate($date) ? 'OK' : 'FAILS') ."\n";
}
?>

It's not elegant plus you'll be limited by Unix Epoch time (from January 1 1970 00:00:00 GMT to January 19 2038 03:14:07 GMT), but it's reliable and it's well supported in PHP. 它不是很优雅,而且会受到Unix Epoch时间的限制(从格林尼治标准时间1970年1月1日00:00:00到格林尼治标准时间2038年1月19日),但是它是可靠的,并且在PHP中得到了很好的支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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