高级文本搜索并从文件中将特定字符串导入VB

时间:2013-02-26 11:48:52

标签: vb.net file search text

我首先要说这是我在VBForums的第一篇文章,我已经潜伏了一段时间。我是VB的新手,我只是学习它来完成我的论文。所以请原谅我的无知。

我要做的是从另一个程序生成的日志文件中读取数据。我需要从该文件中的特定行进入VB以用于其他算法。此日志文件将不断更新,因此如果可能,它需要是实时读取。

如果重要,则从与另一软件通信的USB设备生成日志文件。

以下是日志示例:

`
08:57:00.932    COM12
08:57:00.935    COM11
08:57:00.935    COM10
08:57:00.936    COM9
08:57:00.936    COM8
08:57:00.937    COM7
08:57:00.938    COM6
08:57:00.939    COM5
08:57:00.939    COM4
08:57:00.998    --> 0108000304FF0000
08:57:01.007    <-- 0108000304FF0000

TRF7970A EVM 


08:57:01.014    **** COM Port found! ****
08:57:05.009    --> 010A0003041001210000
08:57:05.009    COM4
08:57:05.173    <-- 010A0003041001210000

Register write request.


08:57:05.173    --> 010C00030410002101020000
08:57:05.280    <-- 010C00030410002101020000

Register write request.


08:57:05.280    --> 010B000304140601000000
08:57:05.715    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:05.716    --> 010A0003041001210000
08:57:05.822    <-- 010A0003041001210000

Register write request.


08:57:05.822    --> 010C00030410002101020000
08:57:05.929    <-- 010C00030410002101020000

Register write request.


08:57:05.929    --> 010B000304140601000000
08:57:06.364    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:06.365    --> 010A0003041001210000
08:57:06.470    <-- 010A0003041001210000

Register write request.


08:57:06.470    --> 010C00030410002101020000
08:57:06.576    <-- 010C00030410002101020000

Register write request.


08:57:06.576    --> 010B000304140601000000
08:57:07.011    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:07.012    --> 010A0003041001210000
08:57:07.117    <-- 010A0003041001210000

Register write request.


08:57:07.117    --> 010C00030410002101020000
08:57:07.223    <-- 010C00030410002101020000

Register write request.


08:57:07.223    --> 010B000304140601000000
08:57:07.658    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:07.659    --> 010A0003041001210000
08:57:07.764    <-- 010A0003041001210000

Register write request.


08:57:07.764    --> 010C00030410002101020000
08:57:07.870    <-- 010C00030410002101020000

Register write request.


08:57:07.870    --> 010B000304140601000000
08:57:08.305    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:08.306    --> 010A0003041001210000
08:57:08.411    <-- 010A0003041001210000

Register write request.


08:57:08.411    --> 010C00030410002101020000
08:57:08.517    <-- 010C00030410002101020000

Register write request.


08:57:08.517    --> 010B000304140601000000
08:57:08.952    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:08.952    --> 010A0003041001210000
08:57:09.058    <-- 010A0003041001210000

Register write request.


08:57:09.058    --> 010C00030410002101020000
08:57:09.164    <-- 010C00030410002101020000

Register write request.


08:57:09.164    --> 010B000304140601000000
08:57:09.585    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]

[AD87851A000007E0,7F]

[,40][,40]D
08:57:09.586    --> 010A0003041001210000
08:57:09.692    <-- 010A0003041001210000

Register write request.


08:57:09.692    --> 010C00030410002101020000
08:57:09.798    <-- 010C00030410002101020000

Register write request.


08:57:09.798    --> 010B000304140601000000
08:57:10.233    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:10.234    --> 010A0003041001210000
08:57:10.340    <-- 010A0003041001210000

Register write request.


08:57:10.340    --> 010C00030410002101020000
08:57:10.446    <-- 010C00030410002101020000

Register write request.

`

我需要能够获得这条线: [AD87851A000007E0,7F]

只是“AD87851A000007E0”然后能够在VB中使用该字符串。这是一个会改变的十六进制代码。

我能够从日志文件中读取,但不能生成有效的输出。

以下是我一直在尝试使用的代码:

Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False
        Do While line IsNot Nothing
            If line.StartsWith("[") Then
                take = False
            End If
            If String.Equals("[" + keyword + ",", line) Then
                take = True
            End If
            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                result.Add(line)
            End If
            line = reader.ReadLine()
    Label1.Text = line
        Loop
    End Using
    Return result
End Function

说实话,我不确定代码是否无效或者我是否只是在将字符串从函数中取出时做错了什么?该函数是否会按原样打印到Label1.Text?

我也试过调用这个函数:

Dim items = ReadData("AD87851A000007E0")

Label1.Text = Convert.ToString(items)

这导致Label1.Text变为“System.Collections.Generic.List`1 [System.String]”


编辑1

Imports System.IO

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("AD87851A000007E0")

    Label1.Text = String.Join(Environment.NewLine, items)


End Sub

Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False
        Do While line IsNot Nothing

            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith("[" + keyword + ",") Then
                take = True
            End If

            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                result.Add(line)
            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

结束班

编辑2_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___

迄今为止的新代码:

Imports System.IO

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("AD87851A000007E0")  ' Calling the specific hex code from the function. Advancement needed to get ALL hex codes.

    '   Dim items1 As String = Convert.ToString(items)
    '   Dim items2 As String = ""


    '   Dim k As Long
    '   k = InStrRev(items, ",")
    '   If k > 0 Then items2 = Left$(items, k)

    Label1.Text = String.Join(Environment.NewLine, items)  'Printing function result to Label1


End Sub


'Function to search log file for a specific hex code. Removes not needed portions of the string. Advancements needed: 
'Find ALL hex codes
'Ignore repeats until a reset is set true
'Store each hex code found in it's own variable for use in algorithms


Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False

        Do While line IsNot Nothing
            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith("[" + keyword + ",") Then
                take = True
            End If


            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                line = line.Remove(0, 1) 'removing the extra parts of the line
                line = line.Remove(16, 4)
                result.Add(line) 'adding the valid result

            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

结束班


编辑3

Imports System.IO

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("[")  ' Calling the specific hex code from the function. Advancement needed to get ALL hex codes.

    Label1.Text = String.Join(Environment.NewLine, items)  'Printing function result to Label1


End Sub


'Function to search log file for a specific hex code. Removes not needed portions of the string. Advancements needed: 
'Find ALL hex codes
'Ignore repeats until a reset is set true
'Store each hex code found in it's own variable for use in algorithms


Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim line1 As String = "COOKIES"
        Dim line2 As String = "COOKIES1"
        Dim line3 As String = "COOKIES2"
        Dim line4 As String = "COOKIES3"
        Dim line5 As String = "COOKIES4"
        Dim line6 As String = "COOKIES5"
        Dim line7 As String = "COOKIES6"
        Dim line8 As String = "COOKIES7"
        Dim line1found = False
        Dim line2found = False
        Dim line3found = False
        Dim line4found = False
        Dim line5found = False
        Dim line6found = False
        Dim line7found = False
        Dim line8found = False
        Dim take = False

        Do While line IsNot Nothing

            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith(keyword) And Not line.StartsWith("[,4") And Not line.StartsWith("[z,") Then
                take = True
            End If

            If line.Contains(line1) Or line.Contains(line2) Or line.Contains(line3) Or line.Contains(line4) Or line.Contains(line5) Or line.Contains(line6) Or line.Contains(line7) Or line.Contains(line8) Then  'attempting to ignore duplicates
                take = False
            End If

            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                line = line.Remove(0, 1) 'removing the extra parts of the line
                line = line.Remove(16, 4)
                result.Add(line) 'adding the valid result

                If line1 <> line And Not line1found Then  'assining results to variables for duplicate elimiation
                    line1 = line
                    line1found = True

                ElseIf line2 <> line And line1 <> line And Not line2found Then
                    line2 = line
                    line2found = True

                ElseIf line <> line3 And line <> line2 And line1 <> line And Not line3found Then
                    line3 = line
                    line3found = True

                ElseIf line <> line4 And line <> line3 And line <> line2 And line <> line1 And Not line4found Then
                    line4 = line
                    line4found = True

                ElseIf line <> line5 And line <> line4 And line <> line3 And line <> line2 And line <> line1 And Not line5found Then
                    line5 = line
                    line5found = True

                ElseIf line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line6found Then
                    line6 = line
                    line6found = True

                ElseIf line7 <> line And line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line7found Then
                    line7 = line
                    line7found = True

                ElseIf line8 <> line And line7 <> line And line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line8found Then
                    line8 = line
                    line8found = True

                End If
            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

结束班

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。第一个问题是您使用的是String.Equals而不是line.StartsWith

If String.Equals("[" + keyword + ",", line) Then
    take = True
End If

您会注意到,在上述代码中,如果整行与字符串&#34; [AD87851A000007E0,&#34;完全匹配],则只会设置take = True。但是你要找的那条线并不等于那个字符串 - 它只是从那个字符串开始。因此,您应该将该代码更改为:

If line.StartsWith("[" + keyword + ",") Then
    take = True
End If

接下来,在读取每一行之后,在循环内设置Label1.Text = line,无论该行是否匹配。你正在做什么会起作用,但可能不是你想要的方式。你现在拥有它的方式,它会用读取的每一个新行覆盖标签的整个文本内容。正如我所说的那样,每一行都是如此,而不仅仅是匹配的那一行。由于你忙于循环,屏幕实际上不会刷新直到你完成,所以最后它只会显示文件的最后一行。

如果您希望它显示所有匹配的行,您需要将其移动到If take...块内,并且需要将这些行连接在一起,如下所示:

If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
    result.Add(line)
    Label1.Text = Label1.Text & Environment.NewLine & line
End If

但是,这仍然不是一个好方法。将UI代码与您的业务逻辑混合在一起绝对不是一个好主意,因此您在调用ReadData后设置标签的直觉是正确的想法。但是,您无法使用Convert.ToString来显示列表的内容。正如您所知,这只会显示数据类型的名称。为此,您需要将列表中的字符串连接成一个字符串,如下所示:

Label1.Text = String.Join(Environment.NewLine, items)

我使用Environment.NewLine作为分隔符,但您可以使用任何您想要的分隔符。例如,如果要在一行中显示所有内容,可以使用", "作为分隔符。

答案 1 :(得分:1)

我迟到了,但这是对Edit 3的修改,以简化一些事情,并创建一个框架,允许您扩展验证线条的方式:

Function readData() As List(Of String)
    readData = New List(Of String)
    Using reader As New StreamReader("C:\rfid-reader.log")
        While Not reader.EndOfStream
            For Each line In reader.ReadToEnd.Split(ControlChars.CrLf)
                If validLine(line) AndAlso Not readData.Contains(line.Split(",")(0).Substring(1)) Then readData.Add(line.Split(",")(0).Substring(1))
            Next
        End While
    End Using
End Function

Private Function validLine(line As String) As Boolean
    validLine = True
    'insert criteria to validate the line's format (you could also look at regex)
    If Not line.Trim.Length > 0 Then
        validLine = False
        Exit Function
    End If
    If Not line.Trim.StartsWith("[") AndAlso line.Trim.EndsWith("]") Then
        validLine = False
        Exit Function
    End If
    If Not line.Split(",").Length = 2 Then
        validLine = False
        Exit Function
    End If
    If Not line.Split(",")(0).Substring(1).Length > 1 Then
        validLine = False
        Exit Function
    End If
    If Not isHex(line.Split(",")(0).Substring(1)) Then
        validLine = False
        Exit Function
    End If
    '...
End Function

Private Function isHex(str As String) As Boolean
    isHex = True
    For i = 0 To str.Length - 1
        If Not {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "B", "C", "D", "E", "F"}.Contains(str.Substring(i, 1)) Then
            isHex = False
            Exit Function
        End If
    Next
End Function