Преобразование строки в многомерный массив для вычисления даты в php

#php #arrays #date #multidimensional-array

#php #массивы #Дата #многомерный массив

Вопрос:

У меня есть строка, как показано ниже

 Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]
 

Я хочу разбить эту строку на многомерный массив и хранить такие дни, как Пн, вт, Ср, в качестве ключей, а значения в квадратных скобках — в качестве значений для каждого дня, как показано ниже, и получать доступ к каждому дню в виде меньших массивов

 Array
(
    [Mon] => [3,9]
    [Tue] => [3,9]
    [Wed] => [5,9]
    [Thu] => [5,11]
    [Fri] => [5,11]
    [Sat] => [5,11]
    [Sun] => [4,10]
)
 

с помощью приведенного ниже кода я смог добиться этого, но такие значения, как [3,9] or [5,11] обрабатываются как строки

     $atd = $utd = "";
    $dod = "20-12-2020";
    $daysArray = "Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]";
    $days = array('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
    preg_match_all("/[[^]]*]/", $daysArray, $matches);
    $dayNum = $matches[0];
    $daysArray = array_combine($days , $dayNum);
    print_r($daysArray);
        
        $valArray = array();
        
        foreach($daysArray as $day=>$val){
            if($day == "Mon" || $day == "Tue"){
              $atd = date("d-m-Y", strtotime(" ".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime(" ".$val[1]." days", $dod));
           }else if($day == "Sun"){
              $atd = date("d-m-Y", strtotime(" ".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime(" ".$val[1]." days", $dod));
           }else if($day == "Wed"){
              $atd = date("d-m-Y", strtotime(" ".$val[0]." days", $dod));
              $utd = date("d-m-Y", strtotime(" ".$val[1]." days", $dod));
           }else{
              $atd = date("d-m-Y", strtotime(" ".$val[0]." 5 days", $dod));
              $utd = date("d-m-Y", strtotime(" ".$val[1]." days", $dod));
             }
            }
        } 
 

когда я печатаю $valArray , это массив, подобный приведенному ниже, что очень плохо.

 array(
   [0]=>[
   [1]=>4
   [2]=>,
   [3]=>1
   [4]=>0
   [5]=>]
);
 

Пожалуйста, помогите

Комментарии:

1. Это фактический код? Вы никогда не устанавливаете какое-либо значение в $valArray

2. Кроме того, $days = array(Mon,Tue,Wed,Thu,Fri,Sat,Sun); недопустимо.

3. Извините за это. Код внутри foreach — это ожидание. Я либо хочу использовать $valArray, либо $ val для получения чисел.

4. @0stone0: обновите его. но это не было проблемой.

Ответ №1:

Я думаю, что это результат, о котором вы просили.

 $str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';

$result = [];

$bits = explode(' ', $str); // explode on space between day names
foreach ( $bits as $bit) {
    $b = explode('[', $bit);    // $bit = Mon[3,9] 
    $b[1] = rtrim($b[1], ']');  // $b0 = Mon, B1 = 3,9] so trim off the last ]
    $result[$b[0]] = explode(',', $b[1]); // explode on , to get inner array
}
print_r($result);
 

Результат

 Array
(
    [Mon] => Array
        (
            [0] => 3
            [1] => 9
        )
    [Tue] => Array
        (
            [0] => 3
            [1] => 9
        )
    [Wed] => Array
        (
            [0] => 5
            [1] => 9
        )
    [Thu] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Fri] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Sat] => Array
        (
            [0] => 5
            [1] => 11
        )
    [Sun] => Array
        (
            [0] => 4
            [1] => 10
        )
)
 

Ответ №2:

Попробуйте это:

 $str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';
// convert main string to array by explode by empty space
$arr = explode(' ', $str);

$newArr = [];

foreach ($arr as $data) {
  // to get all b/n brackets best is to use regEx
  preg_match('#[(.*?)]#', $data, $match);
  // for key of new array use all befor 1st bracket
  // and for content explode data b/n brackets by ','
  $newArr[strtok($data, '[')] = explode(',', $match[1]);
}

var_dump($newArr);
 

Результат:

 array(7) {  ["Mon"]=> array(2) { [0]=> string(1) "3" [1]=> string(1) "9" } 
            ["Tue"]=> array(2) { [0]=> string(1) "3" [1]=> string(1) "9" }    
            ["Wed"]=> array(2) { [0]=> string(1) "5" [1]=> string(1) "9" } 
            ["Thu"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Fri"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Sat"]=> array(2) { [0]=> string(1) "5" [1]=> string(2) "11" } 
            ["Sun"]=> array(2) { [0]=> string(1) "4" [1]=> string(2) "10" } 
    }
 

Комментарии:

1. Спасибо. Но это дает точно такой же результат. [3,9] возвращаются в виде строк

2. ооо не прочитал проблему… Я исправлю это сейчас

Ответ №3:

Вот одно предложение:

 $days = "Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]";
$individualDays = explode(' ', $days);
$result = [];
foreach ($individualDays as $individualDay) {
    $dates = preg_match_all('/d /', $individualDay, $matches);
    $result[substr($individualDay, 0, 3)] = $matches[0];
}
 

Как это работает:

  • Все ваши значения разделены пробелом, поэтому мы сначала разбиваем его, чтобы получить массив отдельных строк ( Mon[3,9] , Tue[3,9] и так далее), которые мы можем перебирать.
  • Первые три символа каждой из этих строк являются обозначением дня, и мы используем их в качестве ключа для нашего нового результирующего массива (используя substr ).
  • Мы сопоставляем все числа в preg_match_all и присваиваем массив совпадений этому ключу.

Комментарии:

1. Спасибо вам за ответ! Но опять же здесь этот substr($individualDay, 0, 3) может привести к проблеме, если цифры чисел внутри скобок увеличиваются.

2. Что вы имеете в виду, если количество цифр увеличивается? При этом извлекаются только первые три символа, которые являются Mon , Tue , и т.д. Это не влияет на количество последующих дат. Вы можете добавить любое количество дат и протестировать, вы увидите, что это дает ожидаемые результаты.

3. @hemanthkumar Вот скрипка с переменным количеством дат, назначенных на каждый день.

4. Ой, извините.! Извлечение дней не было проблемой. Проблема заключалась в том, чтобы присвоить каждому дню соответствующие дополнительные значения в квадратных скобках Mon => (3,9) Wed => (5,9). Мой код работал нормально до истечения нескольких дней. тогда он не рассматривал [3,9] или [5,11] как массив. Ваш ответ верен, но это его часть. Спасибо.

Ответ №4:

Вы также можете использовать шаблон для сопоставления отдельных частей, используя группы захвата и preg_replace_callback .

Передайте массив по ссылке на обратный вызов, чтобы установить значение группы 1 в качестве ключа, и массив со значениями группы 2 и группы 3.

 ([a-z] )[(d ),(d )]
 

Объяснение

  • ([a-z] ) Захватить группу 1, сопоставить 1 символ a-z
  • [ Совпадение [
  • (d ),(d ) Захватите 1 цифры в группе захвата 2 и группе 3 и сопоставьте a , между ними
  • ] Закрытие соответствия ]

Смотрите демонстрацию регулярных выражений и демонстрацию Php

Пример использования совпадения без учета регистра /i

 $pattern = '/([a-z] )[(d ),(d )]/i';
$str = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';
$result = [];

preg_replace_callback(
    $pattern,
    function ($m) use (amp;$result) {
        $result[$m[1]] = [$m[2], $m[3]];
    },
    $str
);

print_r($result);
 

Вывод

 Array
(
    [Mon] => Array
        (
            [0] => 3
            [1] => 9
        )

    [Tue] => Array
        (
            [0] => 3
            [1] => 9
        )

    [Wed] => Array
        (
            [0] => 5
            [1] => 9
        )

    [Thu] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Fri] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Sat] => Array
        (
            [0] => 5
            [1] => 11
        )

    [Sun] => Array
        (
            [0] => 4
            [1] => 10
        )

)
 

Ответ №5:

Это решение преобразует строку в строку JSON путем замены символов. Для создания нужного массива необходим только один json_decode() .

 $input = 'Mon[3,9] Tue[3,9] Wed[5,9] Thu[5,11] Fri[5,11] Sat[5,11] Sun[4,10]';

$strJson = '{"'.strtr($input,[" " => ',"','[' => '":['])."}";
$array = json_decode($strJson, true);

//test output
echo "<pre>".var_export($array, true)."/<pre>";