简体   繁体   English

正则表达式匹配日期和时间

[英]Regex matching a date and time

I'm trying to match a specific datetime format in PHP's regex: 我正在尝试在PHP的正则表达式中匹配特定的日期时间格式:

dd-mm-YYYY HH:ii:ss

It should always be in that format. 它应该始终采用这种格式。 Meaning that for example when it is the first day of the month there must be a leading zero. 举例来说,这意味着当它是一个月的第一天时,必须有一个前导零。 Eg: 例如:

01-01-2013 01:01:01

I tried it with the following pattern: 我尝试了以下模式:

^[0-12]{2}-[0-31]{2}-[0-9]{4} [0-23]{2}:[0-59]{2}:[0-59]{2}$

But the above pattern fails on timestamps like: 09-05-2013 19:45:10 . 但是上述模式在以下时间戳上失败: 09-05-2013 19:45:10

http://rubular.com/r/eGBAhwiNCR http://rubular.com/r/eGBAhwiNCR

I understand this may not be the correct approach to validate a date time like this, but I really want to know what is wrong with the above. 我知道这可能不是验证像这样的日期时间的正确方法,但我真的很想知道上面的问题。

[0-12]{2} matches not the numbers 0 till 12 . [0-12]{2}不匹配数字012 Instead it's a character class allowing 0 to 1 and also the number 2 . 相反,它是一个字符类,允许01以及数字2 The subsequent quantifier just allows the repetition of those, meanding 0,1 or 2 repeated two times. 后续的量词只允许重复这些,意味着重复两次的0,1或2。

Your other placeholders follow the same non-functioning scheme. 您的其他占位符遵循相同的无效方案。

It's best to resort to \\d{2} or \\d{4} if you can't google a better regex. 如果您无法通过Google搜索更好的正则表达式,最好使用\\d{2}\\d{4} Even better yet, just use DateTime to verify the format. 更好的是,只需使用DateTime来验证格式。

The problem is when you are checking the "ranges", for example [0-12] at the beginning. 问题是当您检查“范围”时,例如开头的[0-12] That is a character class, and it is telling the regex to match 0 through 1, and then 2. So if you added more numbers in after the 1st one, it isn't working as you are expecting. 这是一个字符类,它告诉正则表达式先匹配0到1,然后匹配2。因此,如果在第一个之后添加更多数字,则它不能按预期工作。 Changing your regex slightly (focused on the [0-12] initial), [0-319]{2}-[0-12]{2}-[0-9]{4} [0-23]{2}:[0-59]{2}:[0-59]{2}$ , would match 09-01-2011 11:11:10 . 略微更改正则表达式(针对[0-12]首字母), [0-319]{2}-[0-12]{2}-[0-9]{4} [0-23]{2}:[0-59]{2}:[0-59]{2}$ ,将匹配09-01-2011 11:11:10

Ensuring there are valid numbers for each of those spaces requires a little thinking outside the box. 确保每个空格都有有效的数字,需要在框外进行一些思考。 The regex: 正则表达式:

(0[1-9]|[12][\\d]|3[0-2])-(0[1-9]|1[0-2])-[\\d]{4} (0[1-9]|1[\\d]|2[0-3]):(0[1-9]|[1-5][\\d]):(0[1-9]|[1-5][\\d])$

will work for what you are expecting with the regex you attempted . 可以满足您正则表达式的期望。

If you break it down into smaller pieces it makes sense (it looks really scary at the beginning). 如果将其分解成小块,这是有道理的(一开始看起来确实很吓人)。 Looking at the first piece (0-31 for "days"). 看第一部分(“天”为0-31)。

(0[1-9]|[12][\\d]|3[0-2])

This is using an or to handle 3 different cases. 这使用或处理3种不同的情况。

  1. 0[1-9] - a zero followed by any number between 1-9. 0[1-9] -零后跟1-9之间的任何数字。 We don't want [0-9]{2} since that will allow numbers like 00 . 我们不希望[0-9]{2}因为那样会允许使用00这样的数字。 So a number is valid if it starts with 0 and has any other number after it (for single digit days). 因此,如果数字以0开头并且之后有其他任何数字(一位数天),则该数字有效。
  2. [12][\\d] - a 1 or 2 followed by any digit. [12][\\d] 1 or 2后跟任意数字。 This allows the numbers 10-29 to be valid. 这允许数字10-29有效。
  3. 3[0-2] - a 3 followed by anything 0 through 2 matching 30 , 31 , and 32 . 3[0-2] -一个3随后任何0通过2匹配3031 ,和32

Broken down, it's not too bad but this pattern is then carried out for each "field" in your date. 细分而言,还算不错,但是随后针对您日期中的每个“字段”执行此模式。 So this regex validates on each field being valid... but a better way to confirm valid dates maybe needed. 因此,此正则表达式会在每个字段上均进行验证...但是可能需要一种更好的方法来确认有效日期。 This doesn't get into the complexity of checking if you can have 30-02 for example, where February doesn't have 30 days. 例如,这不会涉及检查您是否可以拥有30-02的复杂性,而2月没有30天。

^[0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}$

The example of validation is in php but the regex is standard 验证示例在php中,但是正则表达式是标准的

/*pass the date you wanna validate as parameter to the function.
The function returns true if it is valid and false if the date passed is not valid
*/   
function DateValid($date){
    //format will be fr if the date is in french format and en if the date is in en format
    $format='';
    //regex that tests if the date is in french format or english, if not in one of these two then it is not valid
    if(preg_match("#^(\d{1,2})[\-./ ](\d{1,2})[\-./ ](\d{4})(?: (\d{1,2})(?:[ .-](\d{1,2})){1,2})?$#",$date,$m)){
        $format='fr';
    }elseif (preg_match('#^(\d{4})[-. ](\d{1,2})[-. ](\d{1,2})(?: (\d{1,2})(?:[ .-](\d{1,2})){1,2})?$#', $date, $m)) {
        $format='en';
    }else{
         echo '<p style="font-size:150px">not english nor french</p>';
        return false;
    }
    //If it is french format or English then check if the date is correct
     if($format=='fr'){
         if (checkdate($m[2], $m[1], $m[3]) == false || $m[4] >= 24 || $m[5] >= 60 || $m[6] >= 60) {
            echo '<p style="font-size:150px">Not valid french</p>';
            return false;
        }else{
             echo '<p style="font-size:150px">Valid french</p>';
             return true;
        }
     }elseif($format=='en'){
         if (checkdate($m[2], $m[3], $m[1]) == false || $m[4] >= 24 || $m[5] >= 60 || $m[6] >= 60) {
             echo '<p style="font-size:150px">Not valid english</p>';
             return false;
        }else{
            echo '<p style="font-size:150px">Valid english</p>';
            return true;
        }
     }
}

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

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