header = <<HEADER
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
HEADER

Item = Struct.new(:name, :bits, :range)
RE = /\| *\w+ */

i = 0
table = header.scan(RE).map{|m| Item.new( m.delete(), b = m.size/3, i...(i += b)) }

teststr = 
padding = table.sum(&:bits)
binstr  = teststr.hex.to_s(2).rjust(padding, )

table.each{|el| p el.values}; puts
table.each{|el| puts  % [el.name, el.bits, binstr[el.range] ]}