Reputation: 105
So I have some data from querying a game server and I need to find a way to extract the information so that it can be used on my site.
# 7 "player1" 1156 STEAM_0:4:00100365 0 09:52 84 3 175.77.234.241:27505
# 8 "player2" 1149 STEAM_0:0:39163243 2 14:05 52 0 109.175.131.239:65423
# 9 "player " 1159 STEAM_0:0:162 31 07:19 45 0 78.1.126.130:27025
#10 "gameer123" 1146 STEAM_0:0:701135 4 16:41 94 0 191.200.0.100:14097
The lines above are in the format: "id" "name" "userid" "uniqueid" "frag" "time" "ping" "loss" "adr"
How would I extract this information and turn it into an array so I have something like this
[0] => Array
(
[Id] => 0
[Name] => Player0
[Frags] => 0
[Time] => 50856
[Uniqueid] => STEAM_0:4:001534362
)
[1] => Array
(
[Id] => 0
[Name] => Player1
[Frags] => 4
[Time] => 1447
[Uniqueid] => STEAM_0:4:00100365
)
BTW I only need the players name, frags, time and uniqueid.
Upvotes: 2
Views: 130
Reputation: 1005
I made a few assumptions with your data, and there may be a more simplified regex to accomplish this task, but here is a start in any case.
The following code:
$pattern = '/#\s*(\d+)\s+"([a-zA-Z0-9\s]+)"\s+(\d+)\s+(STEAM_\d+:\d+:\d+)\s+(\d+)\s+(\d+:\d+)\s+(\d+)\s+(\d+)\s+(\d+.\d+.\d+.\d+:\d+)/';
$subject = '# 7 "player1" 1156 STEAM_0:4:00100365 0 09:52 84 3 175.77.234.241:27505
# 8 "player2" 1149 STEAM_0:0:39163243 2 14:05 52 0 109.175.131.239:65423
# 9 "player " 1159 STEAM_0:0:162 31 07:19 45 0 78.1.126.130:27025
#10 "gameer123" 1146 STEAM_0:0:701135 4 16:41 94 0 191.200.0.100:14097';
$lines = explode("\n",$subject);
$allMatches = array();
foreach($lines as $line) {
preg_match($pattern,$line,$matches); // Extract array of fields
$allMatches[] = array(
"Id" => $matches[1],
"Name" => $matches[2],
"Frags" => $matches[5],
"Time" => $matches[6],
"Uniqueid" => $matches[4]
);
}
var_export($allMatches);
Got me this result:
array (
0 =>
array (
'Id' => '7',
'Name' => 'player1',
'Frags' => '0',
'Time' => '09:52',
'Uniqueid' => 'STEAM_0:4:00100365',
),
1 =>
array (
'Id' => '8',
'Name' => 'player2',
'Frags' => '2',
'Time' => '14:05',
'Uniqueid' => 'STEAM_0:0:39163243',
),
2 =>
array (
'Id' => '9',
'Name' => 'player ',
'Frags' => '31',
'Time' => '07:19',
'Uniqueid' => 'STEAM_0:0:162',
),
3 =>
array (
'Id' => '10',
'Name' => 'gameer123',
'Frags' => '4',
'Time' => '16:41',
'Uniqueid' => 'STEAM_0:0:701135',
),
)
As Markus-ao has pointed out, the regex pattern I show here is designed to parse out every element from the strings. To directly solve the problem, the following pattern would be more appropriate:
$pattern = '/#\s*(\d+)\s+"([a-zA-Z0-9\s]+)"\s+(?:\d+)\s+(STEAM_\d+:\d+:\d+)\s+(\d+)\s+(\d+:\d+)/';
Note that this change would also change a match array definition to:
$allMatches[] = array(
"Id" => $matches[1],
"Name" => $matches[2],
"Frags" => $matches[4],
"Time" => $matches[5],
"Uniqueid" => $matches[3]
);
Upvotes: 1
Reputation: 149
You can do this, but you have to remove unwanted data from $arr first.
$game_array = array();
$key = array("id", "name", "frags", "time", "uniqueid");
$str = '7 "player1" 1156 STEAM_0:4:00100365 0 09:52 84 3 175.77.234.241:27505';
$arr = explode(" ", $str);
$arr = array_filter($arr);
$first = array_combine($key, $arr);
$game_array[0] = $first;
Upvotes: 0
Reputation: 26153
$keys = ["id", "name", "userid", "uniqueid", "frag", "time", "ping", "loss", "adr"];
$result = [];
foreach($array as $row){
$row_array = preg_split('/\s+\"([^\"]+)\"\s+|#\s*|\s+/', $row, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$result[] = array_combine($keys, $row_array);
}
var_export($result);
result
array (
0 =>
array (
'id' => '7',
'name' => 'player1',
'userid' => '1156',
'uniqueid' => 'STEAM_0:4:00100365',
'frag' => '0',
'time' => '09:52',
'ping' => '84',
'loss' => '3',
'adr' => '175.77.234.241:27505',
),
1 =>
array (
'id' => '8',
'name' => 'player2',
'userid' => '1149',
'uniqueid' => 'STEAM_0:0:39163243',
'frag' => '2',
'time' => '14:05',
'ping' => '52',
'loss' => '0',
'adr' => '109.175.131.239:65423',
),
2 =>
array (
'id' => '9',
'name' => 'player ',
'userid' => '1159',
'uniqueid' => 'STEAM_0:0:162',
'frag' => '31',
'time' => '07:19',
'ping' => '45',
'loss' => '0',
'adr' => '78.1.126.130:27025',
),
3 =>
array (
'id' => '10',
'name' => 'gameer123',
'userid' => '1146',
'uniqueid' => 'STEAM_0:0:701135',
'frag' => '4',
'time' => '16:41',
'ping' => '94',
'loss' => '0',
'adr' => '191.200.0.100:14097',
),
)
Upvotes: 2
Reputation: 4889
Here's another RegEx approach, using named patterns that are directly recycled into array keys for your clean, final array. You can use any of the RegEx pattern sets suggested here with the solution below, simply add (?<Keyname>...)
at the start of each the patterns' brackets to make them named.
$data = <<<EOL
# 7 "player1" 1156 STEAM_0:4:00100365 0 09:52 84 3 175.77.234.241:27505
# 8 "player2" 1149 STEAM_0:0:39163243 2 14:05 52 0 109.175.131.239:65423
# 9 "player" 1159 STEAM_0:0:162 31 07:19 45 0 78.1.126.130:27025
#10 "gameer123" 1146 STEAM_0:0:701135 4 16:41 94 0 191.200.0.100:14097
EOL;
/* Matching the source data with named patterns */
preg_match_all('#(?<Id>\d+)\s+"(?<Name>[[:alnum:]]+)"\s+\d+\s+(?<Uniqueid>STEAM_[0-9_:]+)\s+(?<Frags>\d+)\s+(?<Time>[\d:]{5})#m', $data, $fields, PREG_SET_ORDER);
/* Cleaning up the numeric keys from RegEx matches */
foreach($fields as $num=>$set) {
$fields[$num] = array_diff_key($set, array_flip( array_filter( array_keys($set), 'is_int')) );
}
print_r($fields);
Results in:
Array
(
[0] => Array
(
[Id] => 7
[Name] => player1
[Uniqueid] => STEAM_0:4:00100365
[Frags] => 0
[Time] => 09:52
)
[1] => Array
(
[Id] => 8
[Name] => player2
[Uniqueid] => STEAM_0:0:39163243
[Frags] => 2
[Time] => 14:05
)
[2] => Array
(
[Id] => 9
[Name] => player
[Uniqueid] => STEAM_0:0:162
[Frags] => 31
[Time] => 07:19
)
[3] => Array
(
[Id] => 10
[Name] => gameer123
[Uniqueid] => STEAM_0:0:701135
[Frags] => 4
[Time] => 16:41
)
)
Note that I've trimmed the third line of your source data from "player "
into "player"
, presume that was a typo. If player names have other characters, add them in: (?<Name>[[:alnum:] _-]+)
etc.
========
I recycled the named-pattern int-key-cleaner into a function, in case someone needs to use often.
/* In place of the foreach-loop above, use: */
$fields = remove_int_keys_pma($fields);
/* And stick these two functions somewhere. */
/* Remove integer keys from preg_match_all sets. (Must use PREG_SET_ORDER.) */
function remove_int_keys_pma($array) {
foreach($array as $k=>$set) {
$array[$k] = remove_int_keys($set);
}
return $array;
}
/* Remove integer keys from an array. */
function remove_int_keys($array) {
return array_diff_key($array, array_flip( array_filter( array_keys($array), 'is_int')) );
}
Upvotes: 2
Reputation: 3081
Yeap same here :)
I've used the Regex 101 website to fine-tune a pattern as accurate as possible to pickup your required segments.
The rest is basically a mechanism to go through them and assemble and print the result.
<?php
$sampleGmeServerResponse = [
'# 7 "player1" 1156 STEAM_0:4:00100365 0 09:52 84 3 175.77.234.241:27505',
'# 8 "player2" 1149 STEAM_0:0:39163243 2 14:05 52 0 109.175.131.239:65423',
'# 9 "player " 1159 STEAM_0:0:162 31 07:19 45 0 78.1.126.130:27025',
'#10 "gameer123" 1146 STEAM_0:0:701135 4 16:41 94 0 191.200.0.100:14097',
];
$keys = ['id', 'name', 'userid', 'uniqueid', 'frag', 'time', 'ping', 'loss', 'adr'];
// The regex made here : https://regex101.com/r/fL9pD7/4 :p
$pattern = '/\s?+(\d+)\s+\"([\w\s]+)\"\s(\d+)\s([\w:"]+)\s+(\d+)\s(\d{2}:\d{2})\s+(\d+)\s+(\d+)\s([\d.:]+)/';
$result = [];
foreach ($sampleGmeServerResponse as $lineOfData) {
$matches = [];
preg_match($pattern, $lineOfData, $matches);
array_shift($matches);
$result[] = array_combine($keys, $matches);
}
print_r($result);
which results to the following output:
Array
(
[0] => Array
(
[id] => 7
[name] => player1
[userid] => 1156
[uniqueid] => STEAM_0:4:00100365
[frag] => 0
[time] => 09:52
[ping] => 84
[loss] => 3
[adr] => 175.77.234.241:27505
)
[1] => Array
(
[id] => 8
[name] => player2
[userid] => 1149
[uniqueid] => STEAM_0:0:39163243
[frag] => 2
[time] => 14:05
[ping] => 52
[loss] => 0
[adr] => 109.175.131.239:65423
)
[2] => Array
(
[id] => 9
[name] => player
[userid] => 1159
[uniqueid] => STEAM_0:0:162
[frag] => 31
[time] => 07:19
[ping] => 45
[loss] => 0
[adr] => 78.1.126.130:27025
)
[3] => Array
(
[id] => 10
[name] => gameer123
[userid] => 1146
[uniqueid] => STEAM_0:0:701135
[frag] => 4
[time] => 16:41
[ping] => 94
[loss] => 0
[adr] => 191.200.0.100:14097
)
)
Upvotes: 0
Reputation: 340
You can use function explode();
$result = [];
$number = 0;
foreach($mysql_result_rows as $row){
$row_array = explode(' ', $row);
$result[$number]['Id'] = trim($row_array['0'], ' ');
$result[$number]['Name'] = trim($row_array['1'], '"');
$result[$number]['Frags'] = trim($row_array['4'], ' ');
$result[$number]['Time'] = trim($row_array['5'], ' ');
$result[$number]['Uniqueid'] = trim($row_array['3'], ' ');
$number++;
}
Upvotes: 1