【问题标题】:Preg Match circumflex ^ in phpPreg匹配抑扬符^在php中
【发布时间】:2010-11-07 14:40:13
【问题描述】:

我无法完全理解 ^ 在我的 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' 没有其他内容(没有日期或月份)它仍然通过真实并显示日期部分,我认为它会引发错误?

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

【问题讨论】:

标签: php regex preg-match


【解决方案1】:

试试这个:

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

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

【讨论】:

    【解决方案2】:

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

    你的模式匹配一​​年,或者一年和一个月,或者一年和一个月和一个日期;如果你跟着括号,你会看到最后的 ? 在一年后围绕整个模式的括号上运行。

    ^    # 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】:

    没有必要对所有东西进行分组。这看起来更好,并且会做同样的事情:

    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" 将开始匹配。

    【讨论】:

    • 这很好地回答了我的问题,并指出了我遇到的具体问题。
    • 您刚刚获得了正确答案,还有 4 个非常好的其他回答,但我觉得您的回答对我想做的事情帮助最大。从来没有这么好的回应,不确定谁来授予“获胜”的答案也是一个很好的问题:)
    【解决方案4】:

    好的,让我们为你分解一下:

    • '~^(\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

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

    【讨论】:

    • 感谢您的演练,它澄清了我遇到的一些问题。
    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多