【问题标题】:Problem with simple regular expression in PHPPHP中简单正则表达式的问题
【发布时间】:2010-02-24 23:09:17
【问题描述】:

解释我的问题的最好方法就是向你展示。

输入字符串:

/04-11-2010/12:45/

获取日期和时间部分的正则表达式:

preg_match('@/(\d\d)-(\d\d)-(\d\d\d\d)/(\d\d):(\d\d)/@', $input, $matches);

PHP 匹配数组:

Array
(
    [0] => /01-11-2010/12:45/
    [1] => 01
    [2] => 11
    [3] => 2010
    [4] => 12
    [5] => 45
)

现在,上面的正则表达式可以完美地获取表示输入字符串中日期和时间的各个组成部分。

问题是时间部分需要是可选的,而不需要降低整个正则表达式。

问题输入字符串:

/04-11-2010//

PHP 匹配数组

Array
(
)

matches 数组需要返回的内容基本上是:

Array
(
    [0] => /01-11-2010/12:45/
    [1] => 01
    [2] => 11
    [3] => 2010
    [4] => 
    [5] => 
)

注意数组元素 4 和 5 仍然需要存在但返回空。

【问题讨论】:

  • 我来晚了!来吧,你不需要正则表达式;)
  • @Rowlf 实际上使用日期只是一个例子。我实际上有一个更大的输入字符串,需要一个正则表达式来提取所有数据。我只需要知道如何捕获不匹配的组。
  • @Camsoft 很公平:)

标签: php regex


【解决方案1】:

使用问号运算符和非捕获组使内容可选。

@/(\d\d)-(\d\d)-(\d\d\d\d)/(?:(\d\d):(\d\d))?/@

我不确定这如何与匹配数组交互 - 如果拥有空数组元素绝对至关重要,您可能需要改为使用

@/(\d\d)-(\d\d)-(\d\d\d\d)/((?:\d\d)?):?((?:\d\d)?)/@

哪个有自己的误报(冒号现在是可选的)。

【讨论】:

    【解决方案2】:

    使第二部分可选:

    '@/(\d\d)-(\d\d)-(\d\d\d\d)/(?:(\d\d):(\d\d))?/@'
    

    这里使用了一个非捕获组(?:…),它不能被引用,因此不会改变匹配组。

    【讨论】:

    • 如果你这样做,第一个 ( 在 / 之后会生成一个新的数组条目,不是吗?或者这就是 (? 在 / 之后的意思吗?那是英文吗?跨度>
    • 不,不会。那是什么?:确实 - 它使它成为一个非捕获组。这意味着一个组可用于使其成为可选(?如在本例中)或重复等,但它不会被捕获为返回值的一部分。
    【解决方案3】:
      @/(\d\d)-(\d\d)-(\d\d\d\d)/((?:\d\d)?):?((?:\d\d)?)/@
    

    做你想做的事(即填充第 4 组和第 5 组),但也接受不完整的时间,如

        /04-11-2010/12:/
    

    不知道你是否满意

    【讨论】:

      【解决方案4】:

      我不是 php-head,但是怎么样:

      preg_match('@/(\d\d)-(\d\d)-(\d\d\d\d)/(\d\d)?:?(\d\d)?/@', $input, $matches);
      

      就正则表达式而言,它应该匹配一个没有时间字段的字符串。

      【讨论】:

        【解决方案5】:

        @OP,不需要凌乱的正则表达式。

        $str="/04-11-2010/12:45/";
        $s = array_filter(explode('/',$str));
        $date=$s[1];
        $time=$s[2];
        $date_parts=explode("-",$date);
        $time_parts=explode(":",$time);
        if ( checkdate($date_parts[1],$date_parts[0],$date_parts[2]) ){
            print "date ok\n";
        }
        

        【讨论】:

        • 好的,所以我们将使用凌乱的 PHP 代替?
        • 别告诉我你不明白它在做什么?
        【解决方案6】:

        使用原生 PHP 函数来完成这项任务,使用正则表达式有点矫枉过正。

        PHP 5 具有date_parse 函数:

        $string = '/04-11-2010/12:45/';
        $dateArray = date_parse(str_replace('/', ' ', $string));
        print_r($dateArray);
        
        $string = '/04-11-2010//';
        $dateArray = date_parse(str_replace('/', ' ', $string));
        print_r($dateArray);
        

        输出:

        Array
        (
            [year] => 2010
            [month] => 11
            [day] => 4
            [hour] => 12
            [minute] => 45
            [second] => 0
            [fraction] => 0
            [warning_count] => 0
            [warnings] => Array
                (
                )
        
            [error_count] => 0
            [errors] => Array
                (
                )
        
            [is_localtime] => 
        )
        
        Array
        (
            [year] => 2010
            [month] => 11
            [day] => 4
            [hour] => 
            [minute] => 
            [second] => 
            [fraction] => 
            [warning_count] => 0
            [warnings] => Array
                (
                )
        
            [error_count] => 0
            [errors] => Array
                (
                )
        
            [is_localtime] => 
        )
        

        PHP 5.3 有一个更灵活的date_parse_from_format 函数,您也可以使用它。

        【讨论】:

        • 谢谢。但这看起来更像是矫枉过正,而不是简单的正则表达式。最后,一个好的正则表达式会更加健壮和灵活。
        猜你喜欢
        • 2011-02-09
        • 1970-01-01
        • 2023-03-31
        • 2011-05-13
        • 2011-04-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多