0

I have a string pulling from a socket: (it is a single string with no escapes (/r/n))

PRODID:-//Microsoft Corporation//Outlook 10.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
X-CALENDARSERVER-ACCESS:PUBLIC
BEGIN:VTIMEZONE
TZID:Pacific Time
BEGIN:STANDARD
DTSTART:20081101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
....

I would like to have it so it is like this:

$data['PRODID'] = -//Microsoft Corporation//Outlook 10.0 MIMEDIR//EN
$data['VERSION'] = 2.0
.......

I did try parse_str but that didn't work. Is there a easy way?

3
  • The problem you are going to run into is that you have duplicate key values.... BEGIN appears twice. Commented Aug 21, 2013 at 21:10
  • Go over the input line by line and split by ":" Commented Aug 21, 2013 at 21:13
  • Provided an answer that shows how to deal with the duplicate key's. Commented Aug 21, 2013 at 21:39

2 Answers 2

1

It would be pretty trivial to write your own script to interpret this.

$lines = explode("\r\n", $string);
$parsed = array();
foreach($lines as $line){
    list($key, $value) = explode(":", $line, 2);
    $parsed[$key] = $value;
}

Immediately I see one point where your script will stop making sense though and that is the duplicate begin key.

To deal with this you can do something along these lines:

$lines = explode("\n", $string);
$parsed = array();
$current = &$parsed;
foreach($lines as $line){
    list($key, $value) = explode(":", $line, 2);
    if ($key == "BEGIN") {
         $parsed[$value] = array();
         $current = &$parsed[$value];
    } else {
         $current[$key] = $value;
    }
}

This will yield output like

Array
(
    [PRODID] => -//Microsoft Corporation//Outlook 10.0 MIMEDIR//EN
    [VERSION] => 2.0
    [METHOD] => PUBLISH
    [X-CALENDARSERVER-ACCESS] => PUBLIC
    [VTIMEZONE] => Array
        (
            [TZID] => Pacific Time
        )

    [STANDARD] => Array
        (
            [DTSTART] => 20081101T020000
            [RRULE] => FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
        )

)

For the above example (note how everything after a begin block is set as a property to a subarray based on the BEGIN's value).

See it in Action

For an Alternative implementation of a iCalendar Parser you can see this question

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, There is no \n (or \r\n), it is a single line retrieved from the socket. I thought I mentioned that, sorry. Your very close. :)
@user1873432 If you are seeing the display as shown (on separate lines) then there is a newline and possibly a carriage return. If that was not the case then the string is all on one line.
Based on the icalendar spec The delimiter should be \r\n. Updated the answer to reflect this.
0

do it like this?

$string = "...." // all the stuff you have there.

$array = array();

// explode on newlines to go through it line by line
foreach(explode("\n", $string) as $line)
{
    // explode again by ':' and set the key/values
    $tmp = explode(':', $line);
    $array[$tmp[0]] = $tmp[1];
}

just be aware that you're going to overwrite keys. (you have BEGIN twice).

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.