2014-03-04 46 views
0

我有一個數據字符串,我想拆分成一個類的列表,將所有數據解析出來,構造器中的不同屬性。每個塊都以一個STX字符開頭,並以一個字符串「PLC」結尾(我不知道廠商爲什麼不使用ETX)將字符串拆分成一個列表(T)

所以基本上,String String將數據流拆分爲字符串「PLC」(並保持它),並把它放入DataList控件(的數據類)

數據流是這樣的:

STX1;0;0;0;0;1;0;0;0;0;0;+3272;-2145;+3273;-2145;PLC\r\nSTX1;0;0;0;0;1;0;0;0;0;0;+3276;-2145;+3272;-2145;PLC\r\nSTX1;0;0;0;0;1;0;0;0;0;0;+3281;-2145;+3272;-2145;PLC\r\n 

,並會導致三個條目中(的數據類)的列表:

STX1;0;0;0;0;1;0;0;0;0;0;+3272;-2145;+3273;-2145;PLC 
STX1;0;0;0;0;1;0;0;0;0;0;+3276;-2145;+3272;-2145;PLC 
STX1;0;0;0;0;1;0;0;0;0;0;+3281;-2145;+3272;-2145;PLC 

我看了,我發現了很多關於拆分字符串的信息,但沒有把它放入類或列表中。我敢肯定,我可以這樣做:

dim datalist as list(of dataclass) 
dim splitdata() as string = datastream.split("PLC") 
for each data as string in splitdata 
    datalist.Add(new dataclass(data)) 
next 

,但我敢肯定有一個更efficant方式(可能使用正則表達式或LINQ,但我不是真的任何familary

感謝英寸!前進

+1

這將有所幫助,如果你有和示例輸入字符串和你想要的對象的輸出。 – Magnus

+0

我已添加您請求的信息。 – BinaryDuck

回答

0

是的,正則表達式會做很好的數據分割成的作品告訴你:

Imports System.Text.RegularExpressions 

Module Module1 

    Sub Main() 
     Dim s = "STX;1;0;0;0;0;1;0;0;0;0;0;+3272;-2145;+3273;-2145;PLC\r\nSTX;1;0;0;0;0;1;0;0;0;0;0;+3276;-2145;+3272;-2145;PLC\r\nSTX;1;0;0;0;0;1;0;0;0;0;0;+3281;-2145;+3272;-2145;PLC" 
     Dim re As New Regex("(STX;.*?;PLC)") 

     Dim matches = re.Matches(s) 

     If matches.Count > 0 Then 
      For i = 0 To matches.Count - 1 
       Console.WriteLine(matches(i).Value) 
       'TODO: do whatever is required with matches(i) 
      Next 
     End If 

     Console.ReadLine() 

    End Sub 

End Module 

輸出:

STX;1;0;0;0;0;1;0;0;0;0;0;+3272;-2145;+3273;-2145;PLC 
STX;1;0;0;0;0;1;0;0;0;0;0;+3276;-2145;+3272;-2145;PLC 
STX;1;0;0;0;0;1;0;0;0;0;0;+3281;-2145;+3272;-2145;PLC 

在上述正則表達式中,括號捕獲的基團,文本部分STX;;PLC是文字匹配,並且.*?匹配任何東西(.)零或更多的時間(*),直到下面的文本。 ?使其「非貪婪」。如果它是貪婪的,它會匹配所有東西,直到最後的;PLC,並且你最終會以整條線作爲匹配。

編輯

在您的意見光,我建議使用String.Split Method (String(), StringSplitOptions)過載:

Module Module1 

    Sub Main() 
     Dim s As String = "STX;1;0;0;0;0;1;0;0;0;0;0;+3272;-2145;+3273;-2145;PLC\r\nSTX;1;0;0;0;0;1;0;0;0;0;0;+3276;-2145;+3272;-2145;PLC\r\nSTX;1;0;0;0;0;1;0;0;0;0;0;+3281;-2145;+3272;-2145;PLC" 
     ' transform the test string to its actual form 
     s = s.Replace("\r\n", vbCrLf) 

     ' split it into the required parts as an array 
     Dim parts() As String = s.Split({vbCrLf}, StringSplitOptions.RemoveEmptyEntries) 

     ' show the split worked as desired 
     For i = 0 To parts.Length - 1 
      Console.WriteLine(String.Format("Part {0}: {1}", i, parts(i))) 
      'TODO: do something with parts(i) 
     Next 

     Console.ReadLine() 

    End Sub 

End Module 

你沒有提到你正在使用的VS版本,所以如果上述投訴有關行

Dim parts() As String = s.Split({vbCrLf}, StringSplitOptions.RemoveEmptyEntries) 

然後請

更換
Dim splitAt() As String = {VbCrLf} 
Dim parts() As String = s.Split(splitAt, StringSplitOptions.RemoveEmptyEntries) 

此外,如果數據被從文件中讀取,那麼你可以使用File.ReadAllLines Method抓住所有行到一個數組中一氣呵成。

+0

This Works!不過,我另外認識到,在不同的文本塊之間還有\ r \ n。所以我實際上可以做一個string.split。所以出於好奇,你知道哪種方法會更有效率,因爲會有6-8個線程一次完成這個任務嗎?我的猜測是string.split()在後臺自動創建類似的東西。但如果它沒有影響,我會用你的方法來看看!(注意我會加註你,但如果我拿到他們,我沒有足夠的聲望點我會回來並且這樣做) – BinaryDuck

+0

@ BinaryDuck當你寫「\ r \ n」時,我認爲你的意思是四個單獨的字符「\ r \ n」。我懷疑String.Split會更快,但是直到你在真實數據上進行測試之後,你才能知道。 –

+0

我實際上是指那些僅僅是二者的ascii字符表示。 – BinaryDuck