Ruby操作CSV格式數據方法詳解
2022-04-18 20:09:41 來源:易采站長站 作者:
CSV格式的數據默認是以逗號分隔各個字段的一條一條記錄,默認用換行符分隔每一條記錄。此外,有的CSV有標題行,有的沒有。還有其他一些格式, 它們都有默認值,但都可以在讀、寫CSV數據時修改默認設置。后文大多數時候故意忽略這些設置,因為絕大多數讀寫操作都使用同樣的參數**options
進行格式設置。例如,在讀取csv文件中的數據時想要忽略標題行,可以在參數中設置headers: true
可設置的項及其默認值包括:
col_sep: ",", #=> 字段分隔符 row_sep: :auto, #=> 記錄分隔符 quote_char: '"', #=> 包圍字段的符號 field_size_limit: nil, #=> 限制字段的字符數量 converters: nil, #=> unconverted_fields: nil, headers: false, #=> 讀取時忽略標題行,具體參考官方手冊 return_headers: false, write_headers: nil, header_converters: nil, skip_blanks: false, #=> 忽略空行 force_quotes: false, #=> 設置為true時,所有字段都將使用被包圍 skip_lines: nil, #=> 指定一個正則(str也會轉換為正則), #=> 匹配的行將被當作注釋行而忽略 liberal_parsing: false, internal_encoding: nil, external_encoding: nil, encoding: nil, nil_value: nil, #=> 使用此處設置的值替換所有nil字段 empty_value: "", #=> 使用此處設置的值替換所有空字符串字段 quote_empty: true, #=> 設置為false時,空字符串字段將轉換為空字段 write_converters: nil, write_nil_value: nil, #=> 將以此處的值替換nil字段寫入文件 write_empty_value: "", strip: false
CSV類方法處理CSV數據
以CSV格式寫入文件
要向文件中寫入CSV格式的數據:
require 'csv' writer = CSV.open('/tmp/file.csv', 'w') writer << ["junmajinlong", 29, 170, true] writer << ["junma", 24, 176, false] writer << ["jinlong", 25, 172, nil] writer << ["majinlong", 23, 173, false] writer.close
寫入完成后,查看:
junmajinlong,29,170,true junma,24,176,false jinlong,25,172, majinlong,23,173,false
注意其中的nil對應的寫入內容為空。
可以直接在語句塊中寫入,這樣的話可以自動關閉CSV.open()打開的IO流:
require 'csv' CSV.open('/tmp/file.csv', 'w') do |writer| writer << ["junmajinlong", 29, 170, true] writer << ["junma", 24, 176, false] writer << ["jinlong", 25, 172, nil] writer << ["majinlong", 23, 173, false] end
CSV.open()打開的是一個封裝后的IO流對象,它除了可以使用CSV單獨為其提供的一些方法(比如這里的<<
)外,還可以使用很多IO流對象的方法,比如seek()、tell()、flush()、eof?()、fsync()等等。
這里使用的<<
方法是單獨為其提供的,它涉及兩個執行過程:
轉換為CSV格式的字符串
如果只是想執行第一個過程,即將數據轉換成CSV格式的字符串而不寫入,可使用類方法generate_line()
:
p CSV.generate_line ["junmajinlong", 29, 170, true] p CSV.generate_line ["jun ma", 24, 176, false] p CSV.generate_line ["jinlong", 25, 172, nil] p CSV.generate_line ["jin, long", 23, 173, false] =begin "junmajinlong,29,170,true\n" "jun ma,24,176,false\n" "jinlong,25,172,\n" "\"jin, long\",23,173,false\n" =end
從CSV格式的文件中讀數據
如果想要讀取CSV文件,可使用類方法read()或別名readlines():
pp CSV.readlines('/tmp/file.csv') =begin [["junmajinlong", "29", "170", "true"], ["junma", "24", "176", "false"], ["jinlong", "25", "172", nil], ["majinlong", "23", "173", "false"]] =end
注意:
讀取CSV文件內容時,每行保存為一個數組,每個字段是這個數組中的一個元素讀取CSV文件內容時,除了不存在的字段轉換為nil外,其它所有的數據都轉換成了字符串類型。所以有時候可能需要去轉換讀取時的數據類型。關于類型轉換,見后文如果要按行讀取CSV文件的內容,使用類方法foreach():
CSV.foreach('/tmp/file.csv') do |row| p row end =begin ["junmajinlong", "29", "170", "true"] ["junma", "24", "176", "false"] ["jinlong", "25", "172", nil] ["majinlong", "23", "173", "false"] =end
從CSV格式的字符串中讀數據
如果想要從字符串中讀取CSV格式的數據,使用parse()和parse_line(),分別用于解析多行字符串和解析單行字符串(超出一行的自動被忽略)。
parse()不指定語句塊時,返回包含解析每一行得到的數組,即一個數組的數組,它是一個csv table類型,有很多自己的方法指定語句塊時,每一行對應的數組傳遞給語句塊控制變量str1=<<-eof junmajinlong,29,170,true jun ma,24,176,false jinlong,25,172, "jin, long",23,173,false eof # 不指定語句塊時,parse返回數組 pp CSV.parse str1 =begin [["junmajinlong", "29", "170", "true"], ["jun ma", "24", "176", "false"], ["jinlong", "25", "172", nil], ["jin, long", "23", "173", "false"]] =end # 指定語句塊時,parse將每行對應的數組傳遞給語句塊 CSV.parse(str1) {|row| p row} =begin ["junmajinlong", "29", "170", "true"] ["jun ma", "24", "176", "false"] ["jinlong", "25", "172", nil] ["jin, long", "23", "173", "false"] =end str2="junmajinlong,29,170,true" p CSV.parse_line str2 ["junmajinlong", "29", "170", "true"]
CSV實例方法處理CSV數據
CSV.new()
、CSV.open()
可以創建csv對象(即一行一行csv格式的數據)CSV.generate()
可將字符串轉換成csv對象并將該對象傳遞給語句塊<<
、puts()
或add_row()
可向CSV目標中(字符串格式的CSV或CSV IO流)寫入行,它們是別名關系gets()
、shift()
、readline()
可從csv對象中讀取一行數據read()
、readlines()
可以讀取csv對象中的所有數據each()
可以從csv對象中迭代每一行eof()
或eof?()
可以判斷是否讀完所有數據rewind()
可以重置當前csv對象的偏移指針line()
可以獲取最近一次讀取的一行數據lineno()
可以獲取當前已讀取的行數path()
可以獲取當前讀取的csv文件名
CSV table
CSV.parse()、CSV.read()、CSV.table()等方法返回的都是數組的數組(二維數組),它們是CSV Table。
CSV table按照表的方式來處理csv數據,比如關注于行、關注于字段的一些操作可以采用csv table相關的方法來處理。
# Headers are part of data data = CSV.parse(<<~ROWS, headers: true) Name,Department,Salary Bob,Engineering,1000 Jane,Sales,2000 John,Management,5000 ROWS data.class #=> CSV::Table data.first #=> #<CSV::Row "Name":"Bob" "Department":"Engineering" "Salary":"1000"> data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"} # Headers provided by developer data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary]) data.first #=> #<CSV::Row name:"Bob" department:"Engineering" salary:"1000">
CSV字段類型轉換
讀取CSV數據時,所有的數據都會轉換為字符串格式。
# Without any converters: CSV.parse('Bob,2018-03-01,100') #=> [["Bob", "2018-03-01", "100"]]
可以在迭代每一行的語句塊中對字段做必要的類型轉換。
但如果類型轉換方式比較簡單,可以在讀取數據時指定converters屬性進行轉換。該屬性的值要么是CSV的內置類型符號,要么是符號數組,要么是一個lambda表達式。有如下內置類型:
Integer Float Numeric (Float + Integer) Date DateTime All
當指定了類型轉換后,每個字段將針對converters的值嘗試做轉換,轉換失敗則保留字段的值不變,所以如果通過lambda自定義類型轉換時也一定要保證這一點。
CSV.parse("1,2,3,4,5", converters: :numeric) #=> [[1, 2, 3, 4, 5]] # With built-in converters: ct = CSV.parse('Bob,2018-03-01,100', converters: %i[numeric date]) #=> [["Bob", #<Date: 2018-03-01>, 100]] ct.first[1] + 1 # 日期對象,加1天 #=> #<Date: 2018-03-02 ((2458180j,0s,0n),+0s,2299161j)> # With custom converters: CSV.parse('Bob,2018-03-01,100', converters: [->(v) { Time.parse(v) rescue v }]) #=> [["Bob", 2018-03-01 00:00:00 +0200, "100"]]
更多關于Ruby操作CSV格式數據方法請查看下面的相關鏈接
如有侵權,請聯系QQ:279390809 電話:15144810328
最新圖文推薦
相關文章
-
蘋果手機電話打不出去怎么辦?iPhone無法撥打電話的解決方法
蘋果手機打不出去電話怎么辦呢?在使用蘋果手機撥打電話時,有時候可能會遇到電話無法撥打出去情況,那么蘋果手機無法撥打電話是什么原因呢?下面我就來為大家介紹一下吧! 蘋果手2020-03-27
-
蘋果手機怎么用Siri控制米家?iPhone控制米家智能設備教程
當前蘋果手機上的米家應用已經更新到4.10版本,新增了對 Siri 捷徑功能的支持。米家支持 Siri 捷徑意味著什么呢?這意味著你可以在蘋果手機上,直接通過 Siri 語音控制米家中的智能設2020-03-28
-
iPhone XR怎么長截圖?iPhone XR滾動截屏兩種方法
很多安卓手機都自帶長截圖功能,而iPhone沒有辦法直接進行長截圖,需要借助第三方軟件,所以很多朋友都不知道怎么操作,下面為大家帶來詳細操作教程。 iPhone XR滾動截屏兩種方法2020-03-27
-
iPhone XR怎么同時登錄兩個微信?iPhone XR雙開微信教程
蘋果iPhone XS Max和XR作為蘋果公司今年最新款手機,擁有了讓人期待的雙開雙待功能,可以讓我們生活一個號,工作一個號。微信同時也離不開我們的生活,很多人要iPhone手機可以同時安2020-03-27
-
iPhone XR收不到微信消息通知怎么辦?iPhone XR微信不提醒的解決方
很多開始使用iPhone XR的朋友反映微信收不到,要打開才能收到,下面小編教大家怎么解決,供大家參考! iPhone XR微信不提醒的解決方法 進入設置界面點擊通用,如下圖所示 在通用界面2020-03-27
-
iphone xs max怎么刷公交?iphone xs max使用NFC坐公交教程
iphone xs max nfc目前只有幾個城市的公交以及apple pay可以使用,更多的功能目前還等官方開放,下面小編教大家怎么使用,供大家參考! iphone xs max使用NFC坐公交教程 首先在主頁找到錢包2020-03-27