匹配字符串中的多个模式并将匹配返回为哈希

时间:2014-06-13 02:05:11

标签: ruby regex hash

我正在处理一些日志文件,试图提取数据。

这是一个文件示例,为了测试,我将加载到名为sample的变量中。 注意:不保证日志文件的列布局在一个文件与下一个文件之间保持一致。

sample = "test script result
Load for five secs: 70%/50%; one minute: 53%; five minutes: 49%
Time source is NTP, 23:25:12.829 UTC Wed Jun 11 2014
                                                          D
MAC Address    IP Address     MAC           RxPwr  Timing I
                              State         (dBmv) Offset P
0000.955c.5a50 192.168.0.1    online(pt)    0.00   5522   N
338c.4f90.2794 10.10.0.1      online(pt)    0.00   3661   N
990a.cb24.71dc 127.0.0.1      online(pt)    -0.50  4645   N
778c.4fc8.7307 192.168.1.1    online(pt)    0.00   3960   N
"

现在,我只是在寻找IPv4和MAC地址;最终搜索将需要包含更多模式。为此,我使用两个正则表达式并将它们传递给Regexp.union

patterns = Regexp.union(/(?<mac_address>\h{4}\.\h{4}\.\h{4})/, /(?<ip_address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)

如您所见,我正在使用命名组来识别匹配项。

我想要实现的结果是哈希。键应该等于捕获组名称,值应该等于正则表达式匹配的值。

示例:

{"mac_address"=>"0000.955c.5a50", "ip_address"=>"192.168.0.1"}
{"mac_address"=>"338c.4f90.2794", "ip_address"=>"10.10.0.1"}  
{"mac_address"=>"990a.cb24.71dc", "ip_address"=>"127.0.0.1"}  
{"mac_address"=>"778c.4fc8.7307", "ip_address"=>"192.168.1.1"}

这是我到目前为止所提出的:

sample.split(/\r?\n/).each do |line|
  hashes = []
  line.split(/\s+/).each do |val|
    match = val.match(patterns)
    if match
      hashes << Hash[match.names.zip(match.captures)].delete_if { |k,v| v.nil? }
    end
  end
  results = hashes.reduce({}) { |r,h| h.each {|k,v| r[k] = v}; r }
  puts results if results.length > 0
end

我觉得应该有更“优雅”的方式来做到这一点。不过,我主要担心的是表现。

0 个答案:

没有答案