Reading INI file with Visual Basic

送分小仙女□ 提交于 2019-12-24 10:14:53

问题


I'm using Visual Basic to read a file which has frequently-used information. Specifically, my file contains information like this:

[Smith]
Name=Sam Smith
Email=sam.smith@yahoo.com
Project=Smith's Treehouse Project
Greeting=Hi Sam,

[Jones]
Name=Josh Jones
Email=josh.jones@gmail.com
Project=Jone's Second-Story Remodel
Greeting=Hi Josh,

I'm then trying to read the info into a simple VB command (actually using Dragon Naturally Speaking, but that shouldn't matter) to send an email in Microsoft Outlook. I don't need to write to the file, or change the values. I just need to read the info, so I can send the email address to the address field, the project name to the subject field, etc. through the use of List Variables.

How do I write a function to read from the file?

I've spent about 4 hours looking for answers here and on other sites, but am confused. (I'm obviously brand new to VB.) It seems like every time I find code that looks kind of close, it uses unique coding functions, so I don't know what the right one is.

Any help appreciated!


回答1:


Perhaps not the most elegant solution, but here's a class that utilizes Regular Expressions to parse the INI:

Imports System.IO
Imports System.Text.RegularExpressions

Public NotInheritable Class IniParser
    Private Shared SectionRegex As New Regex("\[(?<section>[^\n\[\]]+)\]\n*(?<valuelist>(.(?!\[[^\n\[\]]+\]))*)", RegexOptions.Singleline Or RegexOptions.CultureInvariant Or RegexOptions.Compiled)
    Private Shared ValueRegex As New Regex("(?<valuename>[^=\n]+)=(?<value>[^\n]*)", RegexOptions.CultureInvariant Or RegexOptions.Compiled)

    ''' <summary>
    ''' Parses an .ini-file.
    ''' </summary>
    ''' <param name="FileName">The path to the file to parse.</param>
    ''' <remarks></remarks>
    Public Shared Function ParseFile(ByVal FileName As String) As Dictionary(Of String, Dictionary(Of String, String))
        Return IniParser.Parse(File.ReadAllText(FileName))
    End Function

    ''' <summary>
    ''' Parses a text of .ini-format.
    ''' </summary>
    ''' <param name="Data">The text to parse.</param>
    ''' <remarks></remarks>
    Public Shared Function Parse(ByVal Data As String) As Dictionary(Of String, Dictionary(Of String, String))
        Dim Result As New Dictionary(Of String, Dictionary(Of String, String)) '(Section, (Value name, Value))
        Dim Sections As MatchCollection = SectionRegex.Matches(Data)

        'Iterate each section.
        For Each SectionMatch As Match In Sections
            Dim Section As New Dictionary(Of String, String)
            Dim SectionName As String = SectionMatch.Groups("section").Value
            Dim Values As MatchCollection = ValueRegex.Matches(SectionMatch.Groups("valuelist").Value)

            If Result.ContainsKey(SectionName) = True Then
                'A section by this name already exists.
                Dim i As Integer = 1

                'Append a number to the section name until a unique name is found.
                While Result.ContainsKey(SectionName & i)
                    i += 1
                End While

                Result.Add(SectionName & i, Section)
            Else
                'A section by this name does not exist.
                Result.Add(SectionName, Section)
            End If

            'Iterate each value of this section.
            For Each ValueMatch As Match In Values
                Dim ValueName As String = ValueMatch.Groups("valuename").Value
                Dim Value As String = ValueMatch.Groups("value").Value

                If Section.ContainsKey(ValueName) = True Then
                    'A value by this name already exists.
                    Dim i As Integer = 1

                    'Append a number to the value name until a unique name is found.
                    While Section.ContainsKey(ValueName & i)
                        i += 1
                    End While

                    Section.Add(ValueName & i, Value)
                Else
                    'A value by this name does not exist.
                    Section.Add(ValueName, Value)
                End If
            Next
        Next

        Return Result
    End Function
End Class

Example usage

  • Reading values in general:

    Dim IniContents As Dictionary(Of String, Dictionary(Of String, String)) = IniParser.ParseFile("C:\path\to\your\file\here.ini")
    
    For Each SectionName As String In IniContents.Keys
        For Each ValueName As String In IniContents(SectionName).Keys
            Dim Value As String = IniContents(SectionName)(ValueName)
    
            '[SectionName]
            'ValueName=Value
            'ValueName=Value
            '
            'SectionName: The name of the current section (ex: Jones).
            'ValueName  : The name of the current value   (ex: Email).
            'Value      : The value of [ValueName]        (ex: josh.jones@gmail.com).
            Console.WriteLine(SectionName & ": " & ValueName & " = " & Value)
        Next
    Next
    
  • Adding everything to a TreeView, where the node's Tag property is the value:

    Dim IniContents As Dictionary(Of String, Dictionary(Of String, String)) = IniParser.ParseFile("C:\path\to\your\file\here.ini")
    
    For Each SectionName As String In IniContents.Keys
        Dim TopNode As TreeNode = TreeView1.Nodes.Add(SectionName)
        Dim Section As Dictionary(Of String, String) = IniContents(SectionName)
    
        For Each ValueName As String In Section.Keys
            TopNode.Nodes.Add(New TreeNode(ValueName) With {.Tag = Section(ValueName)})
        Next
    Next
    

Screenshot of the TreeView example


Regex pattern explanation

  • SectionRegex:

    \[(?<section>[^\n\[\]]+)\]\n*(?<valuelist>(.(?!\[[^\n\[\]]+\]))*)
    
    \[                         => Match '['.
    (?<section>                => Start of match group "section".
        [^                     => Match any character...
            \n\[\]             => ...that is not '[', ']' or a new line...
        ]+                     => ...and match this one or more times.
    )                          => End of match group "section".
    \]                         => Match ']'.
    \n*                        => Match zero or more new lines
    (?<valuelist>              => Start of match group "valuelist".
        (                      => Start of unnamed match group.
            .                  => Match any character...
            (?!                => ...that is not followed by...
                \[[^\n\[\]]+\] => ...a section...
            )
        )*                     => ...and match this zero or more times.
    )                          => End of match group "valuelist".
    
  • ValueRegex:

    (?<valuename>[^=\n]+)=(?<value>[^\n]*)
    
    (?<valuename>              => Start of match group "valuename".
        [^=\n]+                => Match one or more characters that are not '=' or a new line.
    )                          => End of match group "valuename".
    =                          => Match '='.
    (?<value>                  => Start of match group "value".
        [^\n]*                 => Match zero or more characters that are not a new line.
    )                          => End of match group "value".
    



回答2:


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim a() As String = IO.File.ReadAllLines(iniPath)
    Dim user As String = "Jones"
    Dim data As String = "Project"

    For i = 0 To UBound(a)
        If a(i) = "[" + user + "]" Then
            For j = i To 1000
                If a(j).Contains(data) Then TextBox1.Text = a(j).Replace(data + "=", "") : Exit For
            Next
            Exit for
        End If
    Next
End Sub


来源:https://stackoverflow.com/questions/44093508/reading-ini-file-with-visual-basic

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!