regex — разбирает строку schema.org ‘opensHours’ в переполнении стека

Я хочу преобразовать строки следующим образом:

Мо, Ту, Мы, Чт, Пт 12: 00-18: 00, Сб 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)Я понятия не имею, что еще нужно сделать, чтобы сделать необходимый формат этого текста.

-1

Решение

// 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"}
2

Другие решения

$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>';

Это работает, но это можно использовать только для строки, которую вы дали. Вероятно, есть гораздо более умный способ добиться этого, но он выполняет свою работу.

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;
}
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;
1
По вопросам рекламы [email protected]