题
我不太明白 ^ 在我的 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
}
如我所见,这是在寻找$日期是否匹配我读为4个小数的格式-1或2个小数-1或2个小数
如果匹配,则 IF 语句显示日期,如果不匹配,则会给出日期格式不正确的错误。
但是,仅将其传递给年份$ date ='1977',而没有其他(无日本或一个月),它仍然是正确的并显示了dateParts,我想这会丢下错误吗?
有人能指出我在正则表达式中缺少什么吗?我猜最后的 ^ 或可能是 ?$ 可能意味着只匹配其中的一部分?
解决方案
有没有必要组的绝对一切的。这看起来更好,并会做相同的:
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"
将开始相匹配。
其他提示
尝试这种情况:
'~^(\d\d\d\d)-(\d{1,2})-(\d{1,2})$~'
在问题已得到正则表达式被允许的月份和日期作为任选由“?”字符。
和^
锚$
您的图案的开头和结束分别在传递的字符串。该?
是乘法器,匹配0或前述图案的1(在这种情况下,parenthesised位)。
您模式一年或一年零一个月,或者一年零一个月和日期相匹配;如果你按照括号,你会看到最终的?
是对整个图案的周围的一年后的括号操作。
^ # 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
好吧,让我们为您分解一下:
- '~^(\d\d\d\d)(-(\d{1,2})(-(\d{1,2}))?)?$~'
- ~ - 开头和结尾是 RegExp 分隔符,因此它们实际上并不是正则表达式的一部分。
- ^ - 方法 “这是这条线的开始”
- 避免在字符串中间进行匹配,并对其进行锚定,以便字符串的开头必须匹配
- (\d\d\d\d) - 匹配(并捕获)四位数字,并且不是可选的
- 这也可以写成 \d{4}
- (-(\d{1,2})(-(\d{1,2}))?)? - 匹配(并捕获)一个可选组。
- 它表示如果该组存在,则它必须是破折号,后跟一位或两位数字(日或月),后跟破折号,后跟一位或两位数字(日或月)
- $ - 表示字符串结束,因此与字符串开头的 ^ 一起表示整个字符串必须与正则表达式匹配。
此正则表达式将匹配的一些示例:
- 1982-08-11
- 1982-30-01
- 8127-99-52
一些不匹配的示例:
- 82-08-11
- 2009-10
正如您所看到的,这个正则表达式将接受一些不是真正有效日期的“日期”,所以我可能也会通过某种日期处理函数来运行它,例如 斯特托时间.
不隶属于 StackOverflow