将ruby日志解析器转换为PHP

时间:2014-12-16 21:51:38

标签: php ruby parsing logging

我一直在寻找创建SRCDS(蒸汽游戏服务器)日志解析器,它将数据发送到数据库。 在对其他现有解析器进行研究时,我偶然发现了https://github.com/tomav/steam_hlds_log_parser,这正是https://github.com/tomav/steam_hlds_log_parser/blob/master/lib/steam_hlds_log_parser/handler.rb

elsif @options[:display_disconnect] && data.gsub(/: "(.+)<\d+><.+><(.+)>" disconnected/).count > 0
    player, player_team = data.match(/: "(.+)<\d+><.+><(.+)>" disconnected/i).captures
    content = { :type => 'disconnect', :params => { :player => player, :player_team => get_short_team_name(player_team) } }

虽然data.gsub()非常简单,我猜这与preg_match几乎相同,但变量(player,player_team)部分是个谜。它是如何工作的,并且在没有大量的preg_matches来匹配字符串的不同部分的情况下可以在PHP中进行类似的操作? 上面代码的示例日志字符串是

# L 05/10/2000 - 12:34:56: "Player<73><STEAM_ID_LAN><TERRORIST>" disconnected

1 个答案:

答案 0 :(得分:2)

让我们逐行采取行动:

elsif @options[:display_disconnect] && data.gsub(/: "(.+)<\d+><.+><(.+)>" disconnected/).count > 0

首先检查@options[:display_disconnect]是否真实(即不是falsenil),然后检查data字符串是否与斜杠之间的正则表达式匹配({ {1}})。这是检查Ruby中正则表达式匹配的一种非常糟糕的方法(我们有/.../String#match),但它仍然有效。如果匹配,我们执行下一行:

=~

player, player_team = data.match(/: "(.+)<\d+><.+><(.+)>" disconnected/i).captures 的右侧,我们使用与之前相同的正则表达式调用String#match(但此时间点带有=标志)。如果匹配(我们已在最后一行上建立),i将返回MatchData个对象。该对象包含有关匹配的信息,例如它起始于什么位置,在MatchData#captures属性中,捕获了字符串的哪些部分。

如果您是正则表达式的新手,正则表达式中的括号表示&#34;捕获组。&#34;在我们的正则表达式中,我们有两个:一个捕获玩家名称(&#34;玩家&#34;在您的示例中),另一个捕获团队名称(&#34; TERRORIST&#34;)。 match将这两个字符串作为数组captures返回。

[ "Player", "TERRORIST" ]的左侧,我们有=。逗号表示&#34;解构赋值&#34; -it告诉Ruby,如果player, player_team右侧的值表现得像一个数组,则将第一个元素赋给=并且player的第二个元素,就像PHP中的list()一样。换句话说:

player_team

最后:

player, player_team = [ "Player", "TERRORIST" ]

# ...is equivalent to:

captures = [ "Player", "TERRORIST" ]
player = captures[0]      # => "Player"
player_team = captures[1] # => "TERRORIST"

这会创建一个哈希 - 就像PHP中的关联数组 - 具有content = { :type => 'disconnect', :params => { :player => player, :player_team => get_short_team_name(player_team) } } player值。它在PHP中的粗略等价物是:

player_team

我希望这有用!

P.S。就个人而言,我会像这样编写Ruby代码:

$content = array( "type" => 'disconnect',
                  "params" => array( "player" => $player,
                                     "player_team" => get_short_team_name($player_team) )
                );

我们没有理由两次使用相同的正则表达式,并且当我们实际上没有进行任何替换时,确实没有理由使用DISCONNECT_EXPR = /: "(.+)<\d+><.+><(.+)>" disconnected/i # ... elsif @options[:display_disconnect] && data =~ DISCONNECT_EXPR content = { :type => 'disconnect', :params => { :player => $1, :player_team => get_short_team_name($2) } }