解析csv - 无法识别的文件

时间:2015-09-15 10:52:58

标签: vb.net

只是想得到确认。我们得到了csv文件的解析器。我们收到了昨天在csv文件上看起来不像的文件(逗号分隔或固定)。没有统一的分隔符,或。或标签。发送该文件的人写道:“节点文件不会采用逗号分隔格式,字段分隔也不一致”。所以它不是逗号分隔/或固定文件,它只是一些自定义文件我是对的吗?

格式:

AAP-MCR01-to-MCR02<SPACE>cpsModuleModel<SPACE>9152<SPACE>1<DOUBLESPACE>cpsmM100

示例:

AAP-MCR01-to-MCR02 cpsModuleModel 9152 1  cpsmM100 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 2  cpsDblWide 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 3  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 4  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 5  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 6  cfetf205 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 7  cettf100 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 8  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 9  cettf100 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 10  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 11  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 12  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 13  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 14  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 15  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 16  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 17  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 18  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 125  cpsmp100 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 126  cpsmp100 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 127  cpsEmpty 
AAP-MCR01-to-MCR02 cpsModuleModel 9152 128  cpsEmpty 
AL-MCR01 cpsModuleModel 86209 1  cpsmM100 
AL-MCR01 cpsModuleModel 86209 2  cpsDblWide 
AL-MCR01 cpsModuleModel 86209 3  cfbrm105 
AL-MCR01 cpsModuleModel 86209 4  cfbrm105 
AL-MCR01 cpsModuleModel 86209 5  cfbrm105 
AL-MCR01 cpsModuleModel 86209 6  cfbrm105 
AL-MCR01 cpsModuleModel 86209 7  cfbrm105 
AL-MCR01 cpsModuleModel 86209 8  cfbrm105 

2 个答案:

答案 0 :(得分:1)

这部分有点令人不安:"nor will the field separations be uniform"。希望这是指双打空间,而不是文件到文件。虽然它不是统一的,但我认为这会使它成为一种自定义格式,虽然不是太奇特。

如果你认为你可以采取什么&#34;那家伙&#34;作为一个合同,文件看起来像这样,有两种方法来解析它而不诉诸TextFieldParser。两者都很容易。

AAP-MCR01-to-MCR02<SPACE>cpsModuleModel<SPACE>9152<SPACE>1<DOUBLESPACE>cpsmM100

使用OleDB和Schema导入

由于空间分隔符,您无法最大限度地利用Schema,例如命名列。在与数据文件相同的文件夹中创建Schema.Ini,并添加以下定义块:

[MCRData.csv]
ColNameHeader=false
CharacterSet=ANSI
Format=Delimited( )
DecimalSymbol=.
CurrencySymbol=$

不幸的是,文件中的双重空格将创建一个额外的列,并且当发布时,每行都有一个尾随空格,并创建另一个。这可能是HTML / post格式等的工件。Format条目是单个空格,因为这可能不清楚。

代码很简单:

Dim csvStr As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Temp;Extended Properties='TEXT'"
Dim csvSQL = "SELECT * FROM MCRData.csv"

Using csvCn = New OleDbConnection(csvStr),
         cmd As New OleDbCommand(csvSQL, csvCn)

    Using da As New OleDbDataAdapter(cmd)
        myDT = New DataTable
        da.Fill(myDT)
    End Using

    dgv.AutoGenerateColumns = True
    dgv.DataSource = myDT
End Using

enter image description here

正如我所说,由于分隔符不一致,因此无法定义列,因此它们默认为F1,F2等.F5是双精度空间的伪像,F7是尾随空格的伪像。

字符串拆分

通常String.Split对于实际的CSV来说并不是一个好主意,因为逗号可以是其中一个字段中的合法字符,尤其是作为十进制货币。

在这种情况下,使用空格分隔符,源似乎不太可能在数据中有空格; AAP-MCR01-to-MCR02似乎表明他/她知道这一点。 String.Split也允许一点点清理:

myDT = New DataTable
'ToDo: use better names, may retype some
myDT.Columns.Add("Col1", GetType(String))
myDT.Columns.Add("Col2", GetType(String))
myDT.Columns.Add("Col3", GetType(String))
myDT.Columns.Add("Col4", GetType(String))
myDT.Columns.Add("Col5", GetType(String))

Dim lines = File.ReadAllLines("C:\Temp\MCRData.CSV")
Dim parts As String()
Dim cells As Int32() = {0, 1, 2, 3, 5}

For Each line As String In lines
    ' trim any trailing spaces, cvt dbl space to single
    line = line.Trim.Replace("  ", " ")

    parts = line.Split(" "c)
    If parts.Length = 5 Then
        Dim dr As DataRow = myDT.NewRow

        ' ToDo: conversions
        dr.Item(0) = parts(0)
        dr.Item(1) = parts(1)
        dr.Item(2) = parts(2)
        dr.Item(3) = parts(3)
        dr.Item(4) = parts(4)

        myDT.Rows.Add(dr)
    End If
Next

dr.Item(0) = parts(0)分配可以循环完成,我将其遗漏,因为您可以将一个或两个值转换为数字。结果有点清洁:

enter image description here

VB TextFieldParser也能很好用。它最终几乎与String.Split()方法完全相同。由于尾随空间甚至可能不存在于真实文件中,它将创建第6个虚拟列。

它将处理多个分隔符,但您希望将它们设置为:

Using parser As New TextFieldParser("C:\Temp\MCRData.CSV")
    parser.Delimiters = New String() {"  ", " "}

首先指定双打空格,然后指定空格。它按照给定的顺序切换文本,因此如果首先指定空间,那么最终将使用与OleDb一样的空Col5。

DataTableDataGridView只是一种可视化结果的简单方法。

将文件重新格式化为标准CSV

The problem is i got already huge solution for lot diffrent files not only .csv

在这种情况下,将文件更改为标准CSV非常简单:

Dim inFile As String = "C:\Temp\MCRData.CSV"
Dim outFile As String = "C:\Temp\MCRData.XSV"

Using sr As New StreamReader(inFile)
    Using sw As New StreamWriter(outFile, False)
        Dim line As String
        Do Until sr.EndOfStream
            line = sr.ReadLine

            ' replace doublespace with space
            ' then space with comma
            line = line.Trim.Replace("  ", " ").Replace(" ", ",")
            sw.WriteLine(line)
        Loop
    End Using
End Using

答案 1 :(得分:0)

Wikipedia所述:

  

CSV文件格式的官方标准不存在,但RFC   4180为其的许多方面提供了事实上的标准。在流行   但是,术语CSV可能表示一些密切相关的   分隔符分隔格式,使用各种不同的字段   分隔符。这些包括制表符分隔值和空格分隔   价值,两者都很受欢迎。这些文件经常被给予   .csv扩展,尽管使用了不同的字段分隔符   逗号。这个松散的术语会给数据交换带来问题。

所以,虽然它不包含逗号,但它的定义似乎可以接受以空格分隔的值