我一直在寻找创建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
答案 0 :(得分:2)
让我们逐行采取行动:
elsif @options[:display_disconnect] && data.gsub(/: "(.+)<\d+><.+><(.+)>" disconnected/).count > 0
首先检查@options[:display_disconnect]
是否真实(即不是false
或nil
),然后检查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) }
}
。