Ruby: назначение хэша / разбор текста - PullRequest
0 голосов
/ 17 октября 2010

Нужно создать хеш-таблицу из текстового вывода, которое выглядит следующим образом (пробелы между словами являются вкладками):

GCOLLECTOR     123456     77889     uno  
BLOCK     unique111    error     fullunique111     ...     ...     ...  
DAY     ... ... ...  
LABEL     detail     unique111     Issue     Broken - The truck broke  
LABEL     detail     unique111     Folder    3c1  
LABEL     detail     unique111     Datum     bar_1666.9  
GCOLLECTOR     234567     77889     uno  
BLOCK     unique222    error     fullunique111     ...     ...     ...  
DAY     ... ... ...  
DAY     ... ... ...
LABEL     detail     unique222     Issue     Broken - The truck broke  
LABEL     detail     unique222     Datum     bar_9921.2
LABEL     detail     unique222     Folder    6a3  
GCOLLECTOR     345678     77889     uno  
BLOCK     unique333    error     fullunique111     ...     ...     ...    
LABEL     detail     unique333     Datum     bar_7766.2
LABEL     detail     unique333     Folder    49k  
LABEL     detail     unique333     Issue     Broken - The truck broke

Я хотел бы создать хеш-таблицу, в которой каждому хэшу присваивается следующее:
gcollectors = Hash.new
gcollectors = { "UniqueID" => uniqueXXX,<br> "Datum" => bar_XXXX.X,<br> "FullUniqueID" => fulluniqueXXX,<br> "IssueGroup" => Broken<br> }

Поля uniqueXXX всегда совпадают для BLOCK и связанных меток.

У меня возникла пара проблем:
1- Как мне назначить только эти поля для хэшей?
2- Как я могу разделить текст перед дефисом (в LABEL ... Issue) и назначить его IssueGroup?
3- Как это можно сделать надежно, когда порядок линий LABEL отличается?
.. тот же вопрос, когда есть несколько строк дня или нет строк дня.

Ответы [ 2 ]

0 голосов
/ 17 октября 2010
gcollectors = text.scan(/^GCOLLECTOR.+\n(?:(?:BLOCK|DAY|LABEL).+\n?)+/).map { |collector|
    /^BLOCK\t(?<uniqueid>\S+)\t\S+\t(?<fulluniqueid>\S+).+/ =~ collector
    /^LABEL\t\S+\t\S+\tDatum\t(?<datum>.+)/ =~ collector
    /^LABEL\t\S+\t\S+\tIssue\t(?<issue>\S+)/ =~ collector
    Hash[
        "UniqueID",uniqueid,
        "Datum",datum,
        "FullUniqueID",fulluniqueid,
        "IssueGroup",issue
    ]
}

gcollectors.each{|i|p i}
{"UniqueID"=>"unique111", "Datum"=>"bar_1666.9", "FullUniqueID"=>"fullunique111", "IssueGroup"=>"Broken"}
{"UniqueID"=>"unique222", "Datum"=>"bar_9921.2", "FullUniqueID"=>"fullunique111", "IssueGroup"=>"Broken"}
{"UniqueID"=>"unique333", "Datum"=>"bar_7766.2", "FullUniqueID"=>"fullunique111", "IssueGroup"=>"Broken"}
0 голосов
/ 17 октября 2010

Вот как бы я поступил так:

records     = [] # init an array to hold everything
gcollectors = {} # init the hash holding info for one record

# loop over the file
File.readlines('text.txt').each do |l|

  # split the line into columns
  columns = l.chomp.split("\t")

  # if the first column is...
  case columns[0]
  when 'GCOLLECTOR'
    # we don't care about the columns, but instead use this record to tell us to
    # store the hash and reinitialize it.
    if (gcollectors.any?)
      records << gcollectors
      gcollectors = {}
    end
  when 'BLOCK'
    gcollectors['UniqueID']     = columns[1]
    gcollectors['FullUniqueID'] = columns[3]
  when 'LABEL'
    # a LABEL record could have two different values we care about so figure out
    # which it is.
    case columns[3]
    when 'Datum'
      gcollectors['Datum'] = columns[4]
    when 'Issue'
      gcollectors['IssueGroup'] = columns[4].split('-').first.strip
    end
  end

  # get the next record
  next
end

require 'ap'
ap records
# >> [
# >>     [0] {
# >>             "UniqueID" => "unique111",
# >>         "FullUniqueID" => "fullunique111",
# >>           "IssueGroup" => "Broken",
# >>                "Datum" => "bar_1666.9"
# >>     },
# >>     [1] {
# >>             "UniqueID" => "unique222",
# >>         "FullUniqueID" => "fullunique111",
# >>           "IssueGroup" => "Broken",
# >>                "Datum" => "bar_9921.2"
# >>     }
# >> ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...