我遇到了一个问题,我从服务器上的RCON脚本得到一个相当不规则的字符串输出。当我在服务器上发送返回玩家的命令时,我得到一个如下所示的字符串:
rcon->get_players();
Players on server: [#] [IP Address]:[Port] [Ping] [GUID] [Name] -------------------------------------------------- 0 1.1.1.1:2 46 654321(OK) Player Name1 1 2.2.2.2:2 47 123456(OK) Player Name2 (2 players in total)
如果有帮助,这就是格式化的内容:
Players on server:
[#] [IP Address]:[Port] [Ping] [GUID] [Name]
--------------------------------------------------
0 1.1.1.1:2 46 654321(OK) Player Name1
1 2.2.2.2:2 47 123456(OK) Player Name2
(2 players in total)
所以第一个0是他们在服务器上的密钥ID(0-但是很多玩家),第二个是他们的IP和PORT,47是ping,playerguid是他们的战斗指导,然后是他们在游戏中的名字,然后共有球员回归。
然而,它作为一个大字符串返回。我正在试图找出如何将其提供给数组。所以我得到这样的东西:
array("id"=>"0", "Connection"=>"1.1.1.1:2", "ping"=>"46", "guid"=>"654321", "name"=>"Player Name1");
考虑到输出的不规则性,我能以任何方式实现这一目标吗?在字符串中包含标题会让我失望。
我遵循了Do not Panic的建议并且它已经接近了:UPDATED
echo "Player List:<br />";
$raw_players = $rcon->get_players();
$lines = explode("\n", $raw_players);
$end = count($lines)-1;
$keys = array('id','connection','ping','guid','name');
$regex = '/(\d+)\s+([\d\.\:]+)\s+(\d+)\s+(\d+)\(OK\)\s+(.+)/';
for ($i=3; $i < $end; $i++) {
echo($lines[$i]);
preg_match($regex, $lines[$i], $matches);
unset($matches[0]);
echo(var_dump($matches));
$players[] = array_combine($keys, $matches);
}
我得到了:
Player List:
0 98.193.210.251:2304 47 e0b29e3c7122bda33b5391c22594c776(OK) Colin Fox
array (size=0)
empty
答案 0 :(得分:1)
首先,基于换行符进行爆炸以获取每行的数组。
$lines = explode("\n", $string);
然后你可以像这样构建一个不包括页眉和页脚的for循环:
$end = count($lines) - 1; // this will exclude the last line
for ($i=3; $i < $end; $i++) { // this will start at the fourth line
在循环内部,你可以再次使用exploed,以空格作为分隔符,为每一行获取一个数组。
$players[] = explode(' ', $lines[$i], 5);
这应该有效,因为看起来每行开头的所有值都没有空格。第三个参数(5
)将阻止玩家名称在空间上分割(如果它包含空格),因为它将explode
生成的数组的大小限制为5个元素。
如果希望结果数组具有字符串键,则可以定义键数组(在循环之前):
$keys = array('id', 'connection', 'ping', 'guid', 'name');
然后在循环中使用array_combine创建每个播放器数组。
$players[] = array_combine($keys, explode(' ', $lines[$i], 5));
有了这个字符串的一些新信息,似乎有些列被多个空格(而不是相同数量的空格)分隔,因此爆炸不适用于此。您可以在循环中使用正则表达式匹配。
$keys = array('id', 'connection', 'ping', 'guid', 'name');
$regex = '/(\d+)\s+([\d\.\:]+)\s+(\d+)\s+(\w+)\(OK\)\s+(.+)/';
for ($i=3; $i < $end; $i++) {
preg_match($regex, $lines[$i], $matches);
unset($matches[0]);
$players[] = array_combine($keys, $matches);
}
unset($matches[0]);
是因为preg_match
匹配中的第一个元素将是整个字符串。 $matches
中的每个后续值都将是捕获组的内容。以下是正则表达式的解释:
/ begin pattern
(\d+) capture one or more digits (id)
\s+ skip one or more spaces
([\d\.\:]+) capture one or more characters either digit, dot, or colon (ip/port)
\s+ skip one or more spaces
(\d+) capture one or more digits (ping)
\s+ skip one or more spaces
(\w+) capture one or more alphanumeric characters (guid)
\(OK\)\s+ skip the (OK) and one or more spaces
(.+) capture everything else (player name)
/ end pattern
答案 1 :(得分:0)
答案 2 :(得分:0)
我会在其上使用正则表达式,如下所示:
(\d+) ([\d.:]+) (\d+) (\d+)\([^)]+\) (.*)
与PHP中的preg_match_all
相结合:
preg_match_all('#(\d+) ([\d.:]+) (\d+) (\d+)\([^)]+\) (.*)#', $players, $matches);