Parse Schema.org' OpeningHours' PHP中的字符串

时间:2016-05-31 09:06:45

标签: php regex parsing schema.org

我想像这样转换字符串:

  

Mo,Tu,We,Th,Fr 12:00-18:00,Sa 12:00-16:00

这样的文字:

Monday     12:00-18:00
Tuesday    12:00-18:00
Wednesday  12:00-18:00
Thursday   12:00-18:00
Friday     12:00-18:00
Saturday   12:00-16:00

重命名天数并添加制动器不是问题,但是如何在组中每天添加小时数?

我只做了这件事:str_replace('0,', '0<br>', $opening_hours),我不知道还应该做些什么来制作这个文本所需的格式。

4 个答案:

答案 0 :(得分:2)

// test inputs
// $input = 'Mo,Tu 05:30-22:00, We,Th 06:00-22:00, Fr 06:00-20:00, Sa, Su 10:00-17:30';
// $input = 'Mo 8-18,Tu 8-18, We 8-18, Th 8 -18 ,Fr 8-18, Sa 10-16';
// $input = 'Mo ; Tu,We,Th,Fr,Sa 012:00-12:00';

$input = 'Mo,Tu,We,Th,Fr10:00-21:00,            Sa,Su13:00-19:00';


function parseOpeningHours($input)
{
    // normilize
    $weekdays = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

    $weekdayoptions = implode('|', array_unique($weekdays));

    $unwrapped_input = preg_replace_callback('/\b(' . $weekdayoptions . ')-(' . $weekdayoptions . ')/', function ($matches) use ($weekdays) {
        list (, $from, $to) = $matches;

        $from_idx = array_search($from, $weekdays);

        $to_idx = array_search($to, array_slice($weekdays, $from_idx));

        $unwrapped_range = implode(',', array_slice($weekdays, $from_idx, $to_idx + 1));
        return $unwrapped_range;

    }, $input);

    // find time range for each day of the week
    $result = [
        'Mo' => null,
        'Tu' => null,
        'We' => null,
        'Th' => null,
        'Fr' => null,
        'Sa' => null,
        'Su' => null,
    ];
    $offset = 0;
    while (preg_match('/\b(' . $weekdayoptions . ').*?(\d{1,2})(?::(\d{1,2}))?\s*-\s*(\d{1,2})(?::(\d{1,2}))?/', $unwrapped_input, $matches, PREG_OFFSET_CAPTURE, $offset)) {


        @list (, list ($weekday, $offset), list ($from_hh), list ($from_mm), list ($to_hh), list ($to_mm)) = $matches;

        // normalize the time range
        if ($from_mm == '') $from_mm = '00';
        if ($to_mm == '') $to_mm = '00';
        $time_range = "$from_hh:$from_mm-$to_hh:$to_mm";

        $result[$weekday] = $time_range;
        $offset += strlen($weekday);
    }

    return $result;
}

var_dump(parseOpeningHours($input));

测试输出:

xxxxxxxxx@xxxxxxxxx:~/xxxxxxxxx$ php test.php 
/xxxxxxxxx/test.php:55:
array(7) {
  'Mo' =>
  string(11) "10:00-21:00"
  'Tu' =>
  string(11) "10:00-21:00"
  'We' =>
  string(11) "10:00-21:00"
  'Th' =>
  string(11) "10:00-21:00"
  'Fr' =>
  string(11) "10:00-21:00"
  'Sa' =>
  string(11) "13:00-19:00"
  'Su' =>
  string(11) "13:00-19:00"
}

答案 1 :(得分:1)

$stringToParse = "Mo,Tu,We,Th,Fr 12:00-18:00, Sa 12:00-16:00";
$dayTimeArray = explode( ',', $stringToParse );

$niceWeekDays = array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday');
$niceWeekendDay = array('Saturday');

foreach ( $dayTimeArray as $dayTime ) {
    $dayTime = trim( $dayTime );
    if ( strstr( $dayTime, 'Fr' ) ) {
        $singleDayTimeArray = explode( ' ', $dayTime );
        $timeForWeekDays = $singleDayTimeArray[1];
    }

    if ( strstr( $dayTime, 'Sa' ) ) {
        $singleDayTimeArray = explode( ' ', $dayTime );
        $timeForWeekendDays = $singleDayTimeArray[1];
    }
}

echo '<table>';
foreach ( $niceWeekDays as $weekDay ) {
    echo '<tr><td>' . $weekDay . '</td><td>' . $timeForWeekDays . '</td></tr>';
}

foreach ( $niceWeekendDay as $weekendDay ) {
    echo '<tr><td>' . $weekendDay . '</td><td>' . $timeForWeekendDays . '</td></tr>';
}
echo '</table>';

这有效,但它只适用于你给出的字符串。可能有一种更聪明的方法可以解决这个问题,但它可以完成这项工作。

答案 2 :(得分:1)

试试这个

    <?php
$a1='Mo,Tu,We,Th,Fr 12:00-18:00, Sa 12:00-16:00';

$fridayArr = explode ('Fr ', $a1);
$fridayArr = explode(',', $fridayArr[1]);

$dayNames = array(0=>'Sunday', 1=>'Monday', 2=>'Tuesday', 3=>'Wednesday', 4=>'Thursday', 5=>'Friday', 6=>'Saturday');

$token = strtok($a1, ",");
$i = 1;
$div = '';

while ($token !== false)
   {

if($i<=5) {
   $div .= "$dayNames[$i]  $fridayArr[0]<br>";
} else {
  $div .= str_ireplace('sa', $dayNames[$i], $token) . "<br>";
}

$token = strtok(",");
$i++;
   }
echo $div;

答案 3 :(得分:1)

这些函数可能会对您有所帮助,但请注意,它们假设输入中的最后一个元素将包含间隔:

function getNiceDay($day) {
    switch ($day) {
        case 'Mo': return 'Monday';
        case 'Tu': return 'Tuesday';
        case 'We': return 'Wednesday';
        case 'Th': return 'Thursday';
        case 'Fr': return 'Friday';
        case 'Sa': return 'Saturday';
        case 'Su': return 'Sunday';
    }
}

function convertToStringArray($input) {
    $returnValue = array();
    $days = explode(",", $input);
    $lastIntervalIndex = -1;
    foreach ($index = 0; $index < count($days); $index++) {
        $day = trim($days[$index]);
        $days[$index] = getNiceDay(substr($day, 0, 2));
        if (strlen($day) > 2) {
            $interval = substr($day, strrpos($day, " "));
            for ($intervalIndex = $lastIntervalIndex; $intervalIndex <= $index; $intervalIndex++) {
                $days[$intervalIndex] .= $interval;
            }
            $lastIntervalIndex = $index;
        }
    }
    return $days;
}