Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 写入正则表达式以处理来自外部源的时间集_Php_Regex - Fatal编程技术网

Php 写入正则表达式以处理来自外部源的时间集

Php 写入正则表达式以处理来自外部源的时间集,php,regex,Php,Regex,我正在编写一个脚本,从外部世界接收数据,在那里我查看事件发生的时间,例如,两组时间是: Mon - Fri: 12:00 - 14:00, 18:00 - 22:30, Sat: 18:00 - 22:00 Tue, Wed, Thu: 17:30 - 23:00, Sat: 12:00 - 17:00, Sun: 17:00 - 22:30 如您所见,在每种情况下,数据都以不同的方式显示(周一至周五或周二、周三、周四)。有谁能给我一些关于编写正则表达式/处理形式以将数据放入数组的建议,例如:

我正在编写一个脚本,从外部世界接收数据,在那里我查看事件发生的时间,例如,两组时间是:

Mon - Fri: 12:00 - 14:00, 18:00 - 22:30, Sat: 18:00 - 22:00
Tue, Wed, Thu: 17:30 - 23:00, Sat: 12:00 - 17:00, Sun: 17:00 - 22:30
如您所见,在每种情况下,数据都以不同的方式显示(周一至周五或周二、周三、周四)。有谁能给我一些关于编写正则表达式/处理形式以将数据放入数组的建议,例如:

$timing['mon'][1]['start'] = '12:00';
$timing['mon'][1]['finish'] = '14:00';
$timing['mon'][2]['start'] = '18:00';
$timing['mon'][2]['finish'] = '22:30';

提前感谢。

解决这个问题需要的不仅仅是正则表达式。我先把它分成小块。由于分隔符在该格式中提供双重(或三重)职责,所以不能仅将其沿分隔符拆分,因此需要分块处理。首先,我要把第一个冒号前后的所有东西都拆开。第一部分是您的日期说明符,因此分析它-如果是逗号分隔的列表,只需将其拆分为一个键列表。如果是范围,则使用循环构建键列表。在那之后,你有一个时间列表。我将循环类似于
\d\d:\d\d-\d\d:\d\d、
的内容,直到它无法匹配(指示行的末尾或另一个条目),将每个间隔应用于您先前生成的键集,并在其中为第二个索引增加计数。一旦该模式不匹配,重新开始整个过程:

  • 拆分到第一个冒号以获取日期说明符
  • 将日期说明符处理为一个列表或一个范围(在破折号上匹配可能是为了告诉您有哪种情况)到一个日期列表中
  • 使用下一个逗号或字符串结尾(或使用时间范围模式)获取时间范围
  • 将该时间范围应用于步骤2开始的天数列表
  • 如果有另一个时间模式,则循环回3,否则循环回1
  • 
    

    上面的代码将允许在您的数据中进行更改,正如您将注意到的那样,数组中的键将根据您的数据保留为“Mon-Fri”,因为在格式上没有标准,因此看起来它可能会发生任何更改。

    我想我会尝试一下

    我假设两条不同的线是两个不同的输入。并且没有真正地为错误检查而烦恼。因此,如果格式与您提供的示例有很大差异,则很可能会失败


    您是否可以控制如何从外部世界导入数据?或者你在刮东西什么的?不幸的是没有。。数据来自另一家公司的feed(即完全合法),但数据的呈现方式是固定的。嗨,Richard,谢谢你-我注意到它没有选择周二、周三、周四:部分-似乎只得到周四:部分。有什么建议吗?这是固定的,如果你看一下正则表达式,我添加了逗号,现在对你有用了。:)嗨,Richard,我想感谢你的回复,虽然很有效,但Jacob的解决方案更符合我的目的/每周每天都将所有内容放在一个数组中。不过,我已将您标记为有用。非常感谢,虽然可能不是使用的代码,但我很高兴我提供了帮助,也很高兴您得到了大量的响应,希望您的应用程序运行良好。:)
    
    <?php
    
    $string = "Mon - Fri: 12:00 - 14:00, 18:00 - 22:30, Sat: 18:00 - 22:00
    Tue, Wed, Thu: 17:30 - 23:00, Sat: 12:00 - 17:00, Sun: 17:00 - 22:30";
    
    preg_match_all("/([a-zA-Z\-\s\,]+): ([0-9\:\,\s\-]+)/", $string, $matches, PREG_OFFSET_CAPTURE);
    
    $data = array();
    
    foreach ($matches[1] as $key => $day){
    
        //Split the data and remove whitespace.
        $values = explode(",", $matches[2][$key][0]);
        foreach ($values as $a => $b) $values[$a] = trim($b); if (empty($values[$a])) unset($values[$a]);
    
        //Loop each set and split the stand and end.
        foreach ($values as $a => $b){
    
            $splits = explode("-", $b);
            $values[$a] = array("Start" => $splits[0], "End" => $splits[1]);
    
        } //end foreach
    
        //Place the new data in the array.
        $data[trim($day[0])] = $values;
    
    } //end foreach
    
    echo "<pre>";
    print_r($data);
    
    ?>
    
    <?php
    /**
     * Gets the days of the week in a range. e.g. given Mon Wed, will return an
     * array of Mon, Tue, Wed
     * @param string $start 3 letter day of the week (ucfirst)
     * @param string $end 3 letter day of the week (ucfirst)
     * @return array The days from $start to $end 
     */
    function get_day_range($start, $end) {
        if ($start == $end)
            return array($start);
    
        $date = new DateTime($start);
        $days = array($start);
        while($date->format('D') != $end){
            $date->modify('+1 day');
            $days[] = $date->format('D');
        }
    
        return $days;
    }
    
    /**
     * Checks if the needle exists in the haystack
     * @param string $needle
     * @param string $haystack
     * @return bool 
     */
    function instr($needle, $haystack) {
        return strpos($haystack, $needle) !== false;
    }
    
    function get_event_times($input) {
        preg_match_all('/
            (?<days>(
                (Mon|Tue|Wed|Thu|Fri|Sat|Sun)
                \s*[-,]?\s*
            )+):\s
            (?<times>
                (
                    (
                        \d\d:\d\d
                            \s-\s
                        \d\d:\d\d
                    ),?\s*
                )+
            )/x', $input, $matches, PREG_SET_ORDER);
        $return = array();
    
        foreach($matches as $match) {
            $days = $match['days'];
    
            // Is a day range
            if (instr(' - ', $days)) {
                list($start, $end) = explode(' - ', $days, 2);
                $days = get_day_range($start, $end);
            }
    
            // Is a list of days
            elseif (instr(', ', $days)) {
                $days = explode(', ', $days);
            }
    
            // Is just one day
            else {
                $days = array($days);
            }
    
            $times = trim($match['times'], ', ');
            $times = explode(', ', $times);
    
            foreach($days as $day) {
                foreach($times as $time) {
                    list($start, $end) = explode(' - ', $time);
                    $return[$day][] = array(
                        'start' => $start,
                        'end' => $end
                    );
                }
            }
        }
        return $return;
    }
    
    $inputs = array(
        'Mon - Fri: 12:00 - 14:00, 18:00 - 22:30, Sat: 18:00 - 22:00',
        'Tue, Wed, Thu: 17:30 - 23:00, Sat: 12:00 - 17:00, Sun: 17:00 - 22:30'
    );
    
    foreach($inputs as $input) {
        var_dump(get_event_times($input));
    }