在PHP中Preg匹配circumflex ^

时间:2009-07-02 11:22:05

标签: php regex preg-match

我无法理解我在preg_match中所做的事情。

 if (preg_match('~^(\d\d\d\d)(-(\d{1,2})(-(\d{1,2}))?)?$~', trim($date), $dateParts)) {
   echo the $dateparts and do some magic with them
 } else {
   tell me the date is formatted wrong
 }

正如我所看到的那样,这是为了查看$ date是否符合我所读取的格式 4位小数 - 1或2位小数 - 1或2位小数

如果它匹配则IF语句显示日期,如果不匹配,则它会给出错误的日期格式错误。

然而,只是将它传递给了一年 $ date ='1977'没有别的(没有日期或月份)它仍然是真实的并显示日期部分,我认为它会抛出错误?

有人可以指出我在正则表达式中缺少的内容吗?我猜它是^或者可能是?$最后可能意味着只匹配它的一部分?

4 个答案:

答案 0 :(得分:3)

无需将绝对所有分组。这看起来更好,并将做同样的事情:

preg_match('~^\d{4}(-\d{1,2}(-\d{1,2})?)?$~', trim($date), $dateParts)

这也解释了为什么接受“1977” - 月份和日期部分两者可选(问号使某些内容可选)。

要做你说的(“4位小数 - 1或2位小数 - 1或2位小数”),你需要删除两个可选组:

preg_match('~^\d{4}-\d{1,2}-\d{1,2}$~', trim($date), $dateParts)

^”和“$”与您看到的问题无关。它们只是字符串的开头和字符串结尾的锚点,确保没有别的,而不是模式描述的字符串。将它们关闭,"blah 1977-01-01 blah"将开始匹配。

答案 1 :(得分:2)

试试这个:

'~^(\d\d\d\d)-(\d{1,2})-(\d{1,2})$~'

问题是正则表达式允许月份和日期作为“?”的可选项。字符。

答案 2 :(得分:2)

^$将您的模式分别锚定到传入的字符串的开头和结尾。?是一个乘数,匹配前一个模式的0或1(在此括号中的括号)。

您的模式与一年,一年,一月,一年,一个月和一个日期相匹配;如果你按照括号,你会看到最后的?正在围绕整个模式的parens进行操作。

^    # beginning of string
    (\d\d\d\d)   #year
    (
        -(\d{1,2})   #month after a dash
        (
            -(\d{1,2}) #date after a dash
        )? #date optional
    )?   # month and date optional
$   # end of string

答案 3 :(得分:2)

好的,让我们为你解决这个问题:

  • '〜^(\ d \ d \ d \ d)( - (\ d {1,2})( - (\ d {1,2})))?$〜'
  • - 在开头和结尾都是RegExp-delimiters,因此它们实际上不是正则表达式的一部分。
  • ^ - 表示“这是行的开头”
    • 避免在字符串中间匹配,并锚定它以使字符串的开头必须匹配
  • (\ d \ d \ d \ d) - 匹配(并捕获)四位数字,不是可选的
    • 这也可以写成 \ d {4}
  • ( - (\ d {1,2})( - (\ d {1,2}))?)? - 匹配(并捕获)可选组。
    • 它表示如果该组存在,则必须是破折号,后跟一个或两个数字(日或月),后跟破折号,后跟一个或两个数字(日或月)
  • $ - 表示字符串的结尾,因此,与字符串开头的^一起表示整个字符串必须与Regexp匹配。

此正则表达式匹配的一些示例:

  • 1982年8月11日
  • 1982-30-01
  • 8127-99-52

一些不匹配的例子:

  • 82-08-11
  • 2009-10

正如您所看到的,此正则表达式将接受一些不是真正有效日期的“日期”,因此我可能会通过某种日期处理函数运行它,例如strtotime