2015-09-18 65 views
1

我正在導入一個基本上適用於Groovy的CSV,但不適用於所有字段。用groovy導入CSV ArrayIndexOutOfBoundsException

對於一些領域我得到一個ArrayIndexOutOfBoundsException

我輸入文件看起來像這樣:

Bonbons /t hustenbonbons-und-halsbonbons /t csd00301 /t true /t /t /t Bonbons /t csd00298 /t "<h3>Bonbons</h3>\n<div align=""justify"">Bei Rachenproblemen wie z. B." /t /t 

腳本是這樣的:

inFile.eachLine(){ 
    def fields = it.split("\t") 
    def xsiteCode = fields[0] 
    def seoName = fields[1] 
    def code =  fields[2] 
    def indi =  fields[3] 

當我嘗試時出現錯誤用HTML等閱讀字段(/t "<h3>Bonbons</h3>\n<div align=""justify"">Bei Rachenproblemen wie z. B." /t

(我把它放在製表符的地方)。這是HTML和特殊符號的問題,或者爲什麼我得到這個錯誤,我該如何逃避它?

+0

[使用CSV解析器(https://github.com/xlson/groovycsv) –

+0

你如何更具體並描述它何時有效,何時不起作用?你可以在打印出「it」的「split」調用之後添加println語句,然後再打印出每個字段值的第二個println?失敗的人可能只會打印出「它」。 –

+0

正如我所說的,我可以在你的幫助下解決問題。問題似乎是,並非所有的行都有數據。我得到了所有行都被填充的colums,這些工作,一些colums在最後一行沒有數據,並且它們會崩潰。但他們得到了所有分離器數量(「/ t」),所以我不明白爲什麼這是一個問題? – Mattes

回答

1

ArrayIndexOutOfBoundsException異常引起。 Groovy說:「嘿,你想讓我進入第四個垃圾箱,但沒有垃圾箱。」

如果您確認每行至少有3 \ T的你正在分裂的我想這是因爲你分析自己的換行符(不含3級\ T的)

最低在你的代碼來解決這個侵入性的方式是使用的findAll解析唯一有效的線(與3 \ t的)

inFile.readLines().findAll{ it ==~ /(.*\\t.*){3}/ }.each{ 
    def fields = it.split("\t") 
    def xsiteCode = fields[0] 
+0

您的提示非常好,他聲稱字段更小......「問題」是,並非所有colums都獲得了該行中的數據。我得到了一些colums,其中有12行數據,一些colums數據只有9行。但每個柱子都包含12個分離器「/ t」,所以我不明白爲什麼會出現這個問題? – Mattes

+0

您的文件很有可能以\ n開頭或結尾,這會被解析爲新的(空白/空白)行。分割該行會給你一個大小爲1的數組,你嘗試在4處抓住數組的索引,但它沒有一個,所以拋出異常。即使沒有發生這種情況,當涉及到文件等外部輸入時,防禦性編碼也是一個好主意。 – ScientificMethod

+0

是的,當我把一排放在桌子尾部的所有柱子上時,它就起作用了......所以我猜這也會起作用。謝謝 – Mattes

0

一個問題是逃避正則表達式爲"\\t"。另一個問題(對我來說)是確保文本編輯器不使用軟標籤。

def s = "a  b  c  d" 
def fields = s.split("\\t") 

assert 4 == fields.length 
assert "a" == fields[0] 
assert "b" == fields[1] 
assert "c" == fields[2] 
assert "d" == fields[3] 
+0

轉義爲「\\ t」可悲沒有幫助:/ – Mattes

2

要重申@tim_yates的說法,請爲自己省去頭痛,並考慮使用現有的CSV解析器。它可以讓你轉向更重要的事情。這裏有一個例子:

@Grab('com.opencsv:opencsv:3.5') 

import com.opencsv.CSVReader 

def reader = new StringReader('''Bonbons \t hustenbonbons-und-halsbonbons \t csd00301 \t true \t \t \t Bonbons \t csd00298 \t "<h3>Bonbons</h3>\n<div align=""justify"">Bei Rachenproblemen wie z. B." \t \t''') 

reader.withReader { 
    new CSVReader(it, '\t' as char).each { line -> 
     println line*.trim() 
    } 
} 

的字段是這樣的:當你打電話fields[3]和領域比較小

[Bonbons, hustenbonbons-und-halsbonbons, csd00301, true, , , Bonbons, csd00298, <h3>Bonbons</h3> 
<div align="justify">Bei Rachenproblemen wie z. B.", , ]