2

I have a string as below

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

I want to break this string to multidimensional array and store days like Mon,Tue,Wed as keys and the values inside square brackets as values for each day as below and access each day as smaller arrays

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

with this below code I was able to achieve it but the value such as [3,9] or [5,11] are being treated as strings

    $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));
             }
            }
        } 

when I print $valArray it is a array like below which is very bad.

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

Please help

4
  • 2
    Is this the actual code? You never set any value to $valArray Commented Jan 4, 2021 at 15:05
  • Also, $days = array(Mon,Tue,Wed,Thu,Fri,Sat,Sun); is invalid. Commented Jan 4, 2021 at 15:06
  • Sorry for that. The code inside foreach is the expectation. I either want to use $valArray or $val to get the numbers. Commented Jan 4, 2021 at 15:07
  • @0stone0 : update it. but it was not a problem. Commented Jan 4, 2021 at 15:10

5 Answers 5

2

I think this is the result you were asking for.

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

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
        )
)
Sign up to request clarification or add additional context in comments.

Comments

2

Try this:

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

Result:

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

2 Comments

Thanks. But this gives exactly the same result. [3,9] are returned as strings
oooh didn't read the issue ... Ill fix it now
1

Here's a suggestion:

$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];
}

How it works:

  • All your values are separated by a space, so we first explode by it to get an array of individual strings (Mon[3,9], Tue[3,9] and so on) we can iterate.
  • The first three characters of each of those strings are the day designation and we use that as the key for our new resulting array (utilizing substr).
  • We match all numbers in preg_match_all and assign the array of matches to that key.

4 Comments

Thank you for the answer! But again here this substr($individualDay, 0, 3) could lead to a problem if the digits of the numbers inside the brackets increases.
What do you mean if the number of digits increases? This only extracts the first three characters, which are Mon, Tue, etc. It does not affect the number of dates that follows. You can add any number of dates and test, you'll see it delivers the expected results.
@hemanthkumar Here's a fiddle with a variable number of dates assigned to every day.
Oops Sorry.! Extracting days was not an issue. The issue was to assign each day with respective sub values in the square brackets Mon =>(3,9) Wed=>(5,9). My code was working fine till extracting the days. then it was not considering [3,9] or [5,11] as array. Your answer is correct but it is a part of it. Thank you.
0

You might also use a pattern to match the individual parts using capturing groups and preg_replace_callback.

Pass an array by reference to the callback to set the group 1 value as the key, and an array with the values of group 2 and group 3.

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

Explanation

  • ([a-z]+) Capture group 1, match 1+ a char a-z
  • \[ Match [
  • (\d+),(\d+) Capture 1+ digits in capture group 2 and group 3 and match a , in between
  • ] Match closing ]

See a regex demo and a Php demo

Example using a case insensitive match /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 (&$result) {
        $result[$m[1]] = [$m[2], $m[3]];
    },
    $str
);

print_r($result);

Output

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
        )

)

Comments

0

This solution converts the string to a JSON string by replacing characters. To create the desired array, only one json_decode() is necessary.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.