【问题标题】:.join(',') on Array results in strange results when saving to file保存到文件时,数组上的 .join(',') 会导致奇怪的结果
【发布时间】:2014-10-13 20:41:21
【问题描述】:

我需要进行简单的文件操作。从一个 txt 文件中获取数据并以 csv 格式保存。我的正则表达式正在获取所有数据并将其保存在数组中,但是当我尝试加入数组元素并将其发布到文件中时,它会做一些奇怪的事情。

当调试变量the_line 并通过puts the_line 打印时,这是结果

AN.A-1437/2014 z dnia 2014.04.03
3706
DEZ 1380/2014
Obrót
Wolny rynek
Osoba fizyczna
Osoba fizyczna
334 650.00 zł   
niezabudowana  przeznaczona pod zabudowę inną niż 
WA1L/00022800/1
8 - RAJSZEW
42/2014
9/18
2231 ( LzVI 1402 RVI 829)

但是当我运行out_file.puts(the_line.join(',')) 时,生成的文件看起来像这样

AN.A-1437/2014 z dnia 2014.04.03
,3706
,DEZ 1380/2014
,Obrót
,Wolny rynek
,Osoba fizyczna
,Osoba fizyczna
,334 650.00 zł
,niezabudowana  przeznaczona pod zabudowę inną niż 
,WA1L/00022800/1
,8 - RAJSZEW
,42/2014
,9/18
,2231 ( LzVI 1402 RVI 829)
,Tereny zabudowy usługowej
,Własność
,1/1

这对我来说很奇怪。当我运行test.rb 并手动创建数组并将其保存到文件时,它工作正常。所以我想这与我创建数组的方式有关。但是什么? 完整代码如下:

out_file = File.open('files/out.csv', 'w')
in_file = File.open('files/in.txt')

first_plot = true
the_line = []
n = 0
in_file.each do |line| 
  n += 1
  #the ===== line suggests it's time to save the line and start filling the second one. This is were I have problems somehow
  if line =~ /=+/
    out_file.puts(the_line.join(','))
    the_line = []
    first_plot = true
  #This is because every transaction can have several plots and I have to start new line as well. I know this needs refractoring. 
  elsif line=~ /Numer/
    if !(first_plot)
      if line =~ /:\d+\/*\d*$/
        out_file.puts the_line.join(',')
        13.times { |i| the_line << '' }
      elsif line=~/:\d+\/*\d*;\d+$/
        out_file.puts the_line.join(',')
        19.times { |i| the_line << ''}
      elsif line=~/:\d+\/*\d*;\d+,\d+$/
        out_file.puts the_line.join(',')
        30.times { |i| the_line << ''}
      end
    else 
      #this is the first time the plot is seen so we can have it in one line with transaction details
      first_plot = false
      m = /:(\S.*)$/.match(line)
      the_line << $1
    end
  #This is for every normal value
  elsif line=~/:(\S.*)$/
    the_line << $1
  else
    if line =~ /[a-zA-Z]+ :\s+$/
    else
      puts "#{n}: Error: #{line}"
    end
  end
end
out_file.close
in_file.close

这是我需要操作的示例文件(我想在 : 之后提取值)

Dokument             :AN.A-1437/2014 z dnia 2014.04.03
IRCW                 :3706
Opis                 :DEZ 1380/2014
Rodzaj zapisu        :Obrót
Forma obrotu         :Wolny rynek
Strona sprzedająca   :Osoba fizyczna
Strona kupująca      :Osoba fizyczna
Wartość              :334 650.00 zł

     Nieruchomość              :niezabudowana  przeznaczona pod zabudowę inną niż 
                                zagrodowa
     Księga wieczysta          :WA1L/00022800/1
     Obręb                     :8 - RAJSZEW
     Nr zmiany                 :42/2014
     Działki :                 
         Numer                 :9/18
         Powierzchnia          :2231 ( LzVI 1402 RVI 829)
         Funkcja dominująca    :Tereny zabudowy usługowej
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
====================================================================== : 
Dokument             :AN.A-4778/2014 z dnia 2014.03.03
IRCW                 :3705
Opis                 :DEZ 1352/2014
Rodzaj zapisu        :Obrót
Forma obrotu         :Wolny rynek
Strona sprzedająca   :Osoba fizyczna
Strona kupująca      :Osoba fizyczna
Wartość              :235 000.00 zł

     Nieruchomość              :lokalowa
     Księga wieczysta          :WA1L/00035911/6
     Obręb                     :1 - JABŁONNA
     Nr zmiany                 :767/2014
     Działki :                 
         Numer                 :2273
         Powierzchnia          :2187 ( B 2187)
         Funkcja dominująca    :brak danych
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
     Budynki :                 
         Numer                 :2273;1
         Funkcja podstawowa    :Mieszkalne
         Rok zak. budowy       :2002
         Pow. użytkowa         :2435
         Pow. zabudowy         :1242
         Liczba kond.          :3
         Liczba lokali         :45
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
         adres(y)              :JABŁONNA; LEŚNA 17b
     Lokale :                  
         Numer                 :2273;1,14
         Funkcja podstawowa    :Mieszkalne
         Liczba izb            :3
         Kondygnacja           :1
         Powierzchnia użytkowa :50.23    
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
         adres(y)              :JABŁONNA; LEŚNA 17b
====================================================================== : 
Dokument             :AN.A-5028/2014 z dnia 2014.05.05
IRCW                 :3704
Opis                 :DEZ 1348/2014
Rodzaj zapisu        :Obrót
Forma obrotu         :Wolny rynek
Strona sprzedająca   :Osoba fizyczna
Strona kupująca      :Osoba fizyczna
Wartość              :220 000.00 zł

     Nieruchomość              :niezabudowana  przeznaczona pod zabudowę inną niż 
                                zagrodowa
     Księga wieczysta          :WA1L/00044622/9
     Obręb                     :1 - JABŁONNA
     Nr zmiany                 :765/2014
     Działki :                 
         Numer                 :2759
         Powierzchnia          :1283 ( RIVb 1283)
         Funkcja dominująca    :Tereny zabudowy usługowej
         Rodzaj prawa          :Współwłasność
         Udział w prawie       :1/2
         Numer                 :54/25
         Powierzchnia          :1909 ( RIVb 540 RV 1369)
         Funkcja dominująca    :brak danych
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
         Numer                 :54/26
         Powierzchnia          :2994 ( RV 1318 RIVb 1676)
         Funkcja dominująca    :brak danych
         Rodzaj prawa          :Własność
         Udział w prawie       :1/1
====================================================================== : 

【问题讨论】:

  • 数组中有换行符。在存储之前尝试.chomp。或者使用.map(&amp;:chomp).join(",") 而不仅仅是join(",")
  • 每一行的末尾仍有换行符,例如,如果你运行in_file.each { |l| puts l.length },你会看到额外的字符。
  • cmets 解决问题

标签: ruby arrays regex csv


【解决方案1】:

AS @MarkThomas 指出 .map(&amp;:chomp).join(',') 将清理换行符,但您也可以使用 readlines("\n") 并且您的代码可能会被清理一下,可能是这样的:(尽管即使这段代码也被重构得更多)

def pad_the_line(padding)
  @the_line.concat([''] * padding) 
end
def append_to_output
  @out_file << @the_line.map(&:chomp).join(",")
end
def set_padding(line)
  if line =~ /:\d+\/*\d*$/
    13
  elsif line=~/:\d+\/*\d*;\d+$/
    19
  elsif line=~/:\d+\/*\d*;\d+,\d+$/
    30
  else
    0
  end
end
def process_file(in_file='files/in.txt',out_file='files/out.csv')
  @out_file = File.open(out_file, 'w')
  first_plot = true
  @the_line = []
  File.open(in_file).readlines("\n").each_with_index do |line,index| 
    #the ===== line suggests it's time to save the line and start filling the second one. This is were I have problems somehow
    if line =~ /=+/
      append_to_output
      @the_line.clear
      first_plot = true
    #This is because every transaction can have several plots and I have to start new line as well. I know this needs refractoring. 
    elsif line=~ /Numer/
      if !(first_plot)
        append_to_output
        pad_the_line(set_padding(line))
      else 
      #this is the first time the plot is seen so we can have it in one line with transaction details
        first_plot = false
        m = /:(\S.*)$/.match(line)
        @the_line << $1
      end
    #This is for every normal value
    elsif line=~/:(\S.*)$/
      @the_line << $1
    else
      #you could also raise if needed
      warn "WARNING:: #{index + 1}: Error: #{line}" unless line =~ /[a-zA-Z]+ :\s+$/
    end
  end
  @out_file.close
end

请注意,当我对您的文件运行此命令时,我会得到以下输出

WARNING:: 9: Error:

WARNING:: 11: Error:                                 zagrodowa

WARNING:: 30: Error:

WARNING:: 70: Error:

WARNING:: 72: Error:                                 zagrodowa

和这样的输出文件

AN.A-1437/2014 z dnia 2014.04.03,3706,DEZ 1380/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,334 650.00 zł,niezabudowana  przeznaczona pod zabudowę inną niż ,WA1L/00022800/1,8 - RAJSZEW,42/2014,9/18,2231 ( LzVI 1402 RVI 829),Tereny zabudowy usługowej,Własność,1/1AN.A-4778/2014 z dnia 2014.03.03,3705,DEZ 1352/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,235 000.00 zł,lokalowa,WA1L/00035911/6,1 - JABŁONNA,767/2014,2273,2187 ( B 2187),brak danych,Własność,1/1AN.A-4778/2014 z dnia 2014.03.03,3705,DEZ 1352/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,235 000.00 zł,lokalowa,WA1L/00035911/6,1 - JABŁONNA,767/2014,2273,2187 ( B 2187),brak danych,Własność,1/1,,,,,,,,,,,,,,,,,,,,Mieszkalne,2002,2435,1242,3,45,Własność,1/1,JABŁONNA; LEŚNA 17bAN.A-4778/2014 z dnia 2014.03.03,3705,DEZ 1352/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,235 000.00 zł,lokalowa,WA1L/00035911/6,1 - JABŁONNA,767/2014,2273,2187 ( B 2187),brak danych,Własność,1/1,,,,,,,,,,,,,,,,,,,,Mieszkalne,2002,2435,1242,3,45,Własność,1/1,JABŁONNA; LEŚNA 17b,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Mieszkalne,3,1,50.23    ,Własność,1/1,JABŁONNA; LEŚNA 17bAN.A-5028/2014 z dnia 2014.05.05,3704,DEZ 1348/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,220 000.00 zł,niezabudowana  przeznaczona pod zabudowę inną niż ,WA1L/00044622/9,1 - JABŁONNA,765/2014,2759,1283 ( RIVb 1283),Tereny zabudowy usługowej,Współwłasność,1/2AN.A-5028/2014 z dnia 2014.05.05,3704,DEZ 1348/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,220 000.00 zł,niezabudowana  przeznaczona pod zabudowę inną niż ,WA1L/00044622/9,1 - JABŁONNA,765/2014,2759,1283 ( RIVb 1283),Tereny zabudowy usługowej,Współwłasność,1/2,,,,,,,,,,,,,,1909 ( RIVb 540 RV 1369),brak danych,Własność,1/1AN.A-5028/2014 z dnia 2014.05.05,3704,DEZ 1348/2014,Obrót,Wolny rynek,Osoba fizyczna,Osoba fizyczna,220 000.00 zł,niezabudowana  przeznaczona pod zabudowę inną niż ,WA1L/00044622/9,1 - JABŁONNA,765/2014,2759,1283 ( RIVb 1283),Tereny zabudowy usługowej,Współwłasność,1/2,,,,,,,,,,,,,,1909 ( RIVb 540 RV 1369),brak danych,Własność,1/1,,,,,,,,,,,,,,2994 ( RV 1318 RIVb 1676),brak danych,Własność,1/1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多