Поэтому у меня есть некоторые данные от запроса к игровому серверу, и мне нужно найти способ извлечь информацию, чтобы ее можно было использовать на моем сайте.
# 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
Вышеуказанные строки имеют формат: «id» «name» «userid» «uniqueid» «frag» «time» «ping» «loss» «adr»
Как я могу извлечь эту информацию и превратить ее в массив, чтобы у меня было что-то вроде этого
[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 Мне нужны только имена игроков, фразы, время и уникальный.
Вот еще один подход RegEx, используя именованные шаблоны, которые непосредственно перерабатываются в ключи массива для вашего чистого финального массива. Вы можете использовать любой набор наборов (?<Keyname>...)
предложенный здесь с приведенным ниже решением, просто добавьте (?<Keyname>...)
в начале каждого скобки шаблонов, чтобы сделать их названными.
$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);
,$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);
Результаты в:
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 ) )
Обратите внимание, что я обрезал третью строку ваших исходных данных с "player "
на "player"
, предположим, что это была опечатка. Если имена игроков имеют другие символы, добавьте их в: (?<Name>[[:alnum:] _-]+)
и т. Д.
========
Я переработал int-key-cleaner с именованным шаблоном в функцию, если кому-то нужно часто пользоваться.
/* 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')) ); }
$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);
результат
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', ), )
Вы можете использовать функцию 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++; }
Я сделал несколько предположений с вашими данными, и для выполнения этой задачи может быть упрощенное регулярное выражение, но в любом случае это начало.
Следующий код:
$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);
Получил мне этот результат:
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', ), )
Как отметил Markus-ao, шаблон регулярного выражения, который я показываю здесь, предназначен для анализа каждого элемента из строк. Чтобы непосредственно решить проблему, более подходящей была бы следующая схема:
$pattern = '/#\s*(\d+)\s+"([a-zA-Z0-9\s]+)"\s+(?:\d+)\s+(STEAM_\d+:\d+:\d+)\s+(\d+)\s+(\d+:\d+)/';
Обратите внимание, что это изменение также изменит определение массива совпадений так:
$allMatches[] = array( "Id" => $matches[1], "Name" => $matches[2], "Frags" => $matches[4], "Time" => $matches[5], "Uniqueid" => $matches[3] );
Yeap же здесь 🙂
Я использовал веб-сайт Regex 101 для точной настройки шаблона как можно точнее, чтобы выбрать нужные сегменты.
Остальное – это в основном механизм, позволяющий пройти через них, собрать и распечатать результат.
<?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);
что приводит к следующему результату:
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 ) )
Вы можете это сделать, но сначала нужно удалить ненужные данные из $ arr.
$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;