Jump to content

Converting a Complex String to Array/Table


netbookpros

Recommended Posts

Receiving the below message over UDP as a string from a game server. (All details have been changed to protect anonymity.) What would be the most efficient way to parse this into an array/table of the format outlined at the start of the string. I'm aware of pregsplit() and explode() and that I probably need to find the # each time then rerun the match incremented by one to find the next record. But I can't get my head around how I would divide this string up as they wouldn't always be of the same length. There could be anywhere between 0 and 64 records returned. Thanks for any help.

 

 

Players on server: [#] [iP Address]:[Port] [Ping] [GUID] [Name] -------------------------------------------------- 0 149.223.37.234:2304 171 as1wd5sjg095fc5xdv9u2x4mmigxi6fe Billyo 1 52.157.123.12:2304 156 jmmga2qza05vg0j84xhglrzdbuqe37wp {A}Gamer 2 248.237.161.275:204 63 0l0d2lxuiwejafp8b8aag1psqmbtgwos Kokonuts 3 35.195.183.151:2304 46 iuww8nvzh5a22rcesjj9jdlkrt2laj99 XSD-T. Marshall 4 44.101.11.241:2304 62 msclrtyaoc2go6cqfxzxbnuo6mtx42l5 5 199.285.163.153:2404 46 n9juys2as7jbkeqgx2913t543evp5w7m Muy 6 54.174.123.135:2304 46 bf713bf4bef6f6a4055416d96b9459ff lotto (6 players in total)

 

Link to comment
Share on other sites

well, assuming you won't ever get a malformed response, you know that the number of entries will be the number of entries in the exploded array divided by 4. So for example, you could explode by the space character " ". and then go through exploded array, 4 at a time. for example

$str = "however you get the string";
$pieces = explode(" ", $str);

//go through it 4 at a time
for ($i = 0; $i < sizeOf($pieces); $i += 4){
$piece1 = $pieces[$i];
$piece2 = $pieces[$i+1];
$piece3 = $pieces[$i+2];
$piece4 = $pieces[$i+3];
}

 

 

Link to comment
Share on other sites

Mikesta's approach sounds good, though you should remove the header and footer first (or just remove the header and ignore the footer when you reach it).  And it looks like there's 5 data points per user, so you would go through 5 at a time.

Link to comment
Share on other sites

Mikesta's approach sounds good, though you should remove the header and footer first (or just remove the header and ignore the footer when you reach it).  And it looks like there's 5 data points per user, so you would go through 5 at a time.

 

oh yes, thanks for catching that.

Link to comment
Share on other sites

Thank you for the quick response. I'm not sure that method is going to work correctly as the space character is allowed in the name field. So a name could be 'Jim Bob.' The explode function would surely then split the entry into two records and ruin the whole process? Unfortunately I have no control over the format of the server message so I can't introduce any convenient spacers.  :-\

 

Edit: As for malformed responses, its unlikely that this will occur as the packets have checksums and sequence numbers that have already been checked prior to this point in the code. Failing a major bug server side, bad data shouldn't have made it this far in the program.

Link to comment
Share on other sites

Ahh yes thats true. If that is the case you are going to have to have a special condition where you keep checking the next index if you are going to go with explode. However, that being the case, you may want to go with a regular expression

Link to comment
Share on other sites

Please tell me that the name field can't have numbers in it.. otherwise it's tricky.  You might want to make a second post in the regexp sub-forum asking specifically about a regexp to parse this.  I would not consider that to be double posting as you're asking a different question.

 

Also the name for #4 appears to be missing altogether, further complicating things.  Does that data go through any earlier processing phases which might have a more structured format?

 

This code works for all except #4 (and assumes specific characters allowed in the name - this would need to be altered for other names.  It also won't work if numbers are allowed in names):

<?php
$str = 'Players on server: [#] [iP Address]:[Port] [Ping] [GUID] [Name] -------------------------------------------------- 0 149.223.37.234:2304 171 as1wd5sjg095fc5xdv9u2x4mmigxi6fe Billyo 1 52.157.123.12:2304 156 jmmga2qza05vg0j84xhglrzdbuqe37wp {A}Gamer 2 248.237.161.275:204 63 0l0d2lxuiwejafp8b8aag1psqmbtgwos Kokonuts 3 35.195.183.151:2304 46 iuww8nvzh5a22rcesjj9jdlkrt2laj99 XSD-T. Marshall 4 44.101.11.241:2304 62 msclrtyaoc2go6cqfxzxbnuo6mtx42l5 5 199.285.163.153:2404 46 n9juys2as7jbkeqgx2913t543evp5w7m Muy 6 54.174.123.135:2304 46 bf713bf4bef6f6a4055416d96b9459ff lotto (6 players in total)';

$str = preg_replace('|.*-------------------------------------------------- |', '', $str);
$str = preg_replace('|\(\d+ players in total\)|', '', $str);
print "$str\n";

$foo = preg_match_all('|(\d+) ([\d.:]+) (\d+) ([[:alnum:]]+) ([[:alpha:]. {}-]+) |', $str, &$matches);
var_dump($matches);
?>

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.