2

いくつかの異なるセクションを含むテキスト ファイルがあります。各セクションにはヘッダーがあり、その後に実際のデータが続きます。例えば:

Header1
x,y,z
x,y,z
x,y,z
Header2
a,b,c
a,b,c
a,b,c

ファイルを 1 回のパスで読み取り、各セクションの下にあるデータを使用してさまざまなことをしたいと考えています。データを解析する方法は知っていますが、「Header2 にヒットするまでこれを行い、Header3 まで別のことを行うなど」のロジックをコーディングする方法を理解するのに苦労しています。

私はルビーを使用していますが、これを行う例に実際に遭遇したことはありません。助言がありますか?

4

4 に答える 4

1

最も簡単には、次のようなことができます。

# Process lines for header1
def do_header1(line)
  puts line.split(/,/).join("|")
end

# Process lines for header2
def do_header2(line)
  puts line.split(/,/).map{ |e| e.upcase}.join(",")
end

header1 = false
header2 = false

# Main loop
File.open("file.txt").each_line do |line|
  if line.chomp == 'Header1' # or whatever match for header1
    header1 = true
    header2 = false
    next
  end
  if line.chomp == 'Header2' # or whatever match for header2
    header1 = false
    header2 = true
    next
  end

  do_header1(line) && next if header1
  do_header2(line) && next if header2

end

ヘッダーの数が多くなりすぎた場合は、整数を使用してヘッダーの追跡を開始できます。

header = -1

# Main loop
File.open("file.txt").each_line do |line|
  if line.chomp == 'Header1' # or whatever match for header1
    header = 1
    next
  end
  if line.chomp == 'Header2' # or whatever match for header2
    header = 2
    next
  end

  do_header1(line) && next if header == 1
  do_header2(line) && next if header == 2

end
于 2012-04-07T21:17:18.760 に答える
1

オブジェクトを使用したソリューション。各行について、パーサーが解析できる新しいセクションが開始されているかどうかを各パーサーに尋ねます。

class Section1Parser
  def section? potential_header
    potential_header.chomp == 'Header1'
  end
  def parse line
    puts "Section 1: #{line.split(/,/).join("|")}"
  end
end

class Section2Parser
  def section? potential_header
    potential_header.chomp == 'Header2'
  end
  def parse line
    puts "Section 2: #{line.split(/,/).join("|")}"
  end
end

parsers = [Section1Parser.new, Section2Parser.new]
selected_parser = nil

File.open("c:\\temp\\file.txt").each_line do |line|
  if new_parser_detected = parsers.detect {|p| p.section? line }
    selected_parser = new_parser_detected 
    next # skip header
  end
  selected_parser.parse line if selected_parser
end
于 2012-04-07T21:35:05.917 に答える
0

私の場合、「ヘッダー」は次の文字列の形式でしたOBJECT ObjectType ObjectNumber ObjectName

if File.exist?("all.txt") then  
    object_file = File

    File.open("all.txt").each_line do |line|
        file_name = case 
            when line.match('^OBJECT Table.*')
                "TAB" + line.split[2] + ".TXT"
            when line.match('^OBJECT Form.*')
                "FOR" + line.split[2] + ".TXT"
            when line.match('^OBJECT Report.*')
                "REP" + line.split[2] + ".TXT"
            when line.match('^OBJECT Dataport.*')
                "DAT" + line.split[2] + ".TXT"
            when line.match('^OBJECT XMLPort.*')
                "XML" + line.split[2] + ".TXT"
            when line.match('^OBJECT Codeunit.*')
                "COD" + line.split[2] + ".TXT"
            when line.match("^OBJECT MenuSuite.*")
                "MEN" + line.split[2] + ".TXT"
            when line.match('^OBJECT Page.*')
                "PAG" + line.split[2] + ".TXT"
            when line.match('^OBJECT Query.*')
                "QUE" + line.split[2] + ".TXT"
        end

        unless file_name.nil? 
            File.exist?(file_name) { File.delete(file_name) }
            object_file = File.open(file_name,"w")
        end

        object_file.write(line)
    end 
end

ただし、いくつかの前提条件があります。ファイルの最初の行にヘッダーが含まれていることは常に確信しています。また、ファイルを閉じていません(これにより、私のカルマがいつかゼロになることは間違いありません)。

于 2012-06-06T10:15:49.563 に答える
0

このようなものは機能しますか?

File.open('datafile').each_line do |s|
  if s =~ /^headerpattern$/
    #Start a new parsing block
    ...
  else
    #Parse data
    ...
  end
end
于 2012-04-07T21:11:06.190 に答える