我有一个数据字符串,我想拆分成一个类列表,将所有数据解析为构造函数中的不同属性。每个块以STX字符开头,以字符串“PLC”结尾(我不知道为什么供应商不使用ETX)
所以基本上需要String数据流将字符串“PLC”拆分(并保留它)并将其放入dataList(DataClass)
数据流如下所示:
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
但我确信有一种更有效的方式(可能使用正则表达式或LINQ,但我对它们都不熟悉。
提前致谢!
答案 0 :(得分: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一次性将所有行抓取到数组中。