简体   繁体   中英

Regex how to get custom section text

I write a .Net application that needs parser to parse files, containing sections like this:

[Params]
testParam = false
[Data]
testdata
[Info]
//sominfo

As you can see this file contains 3 sections. Sections header can be different, for example, here it is [{Text}] and it can be ${Text}. I want to give user a possibily to specify header pattern. So is there a regex, that can extract text of section, for example for section [Params] text is testParam = false, for section [Data] text is testdata etc.

I'm not very good in regex and will be very gratefull for any help

To parse for a specific value, lets say Params :

\[Params][\s\n\r]+([^\[]*)

To parse for all the values:

\[[^\]]+\][\s\n\r]+([^\[]*)

It seems to be an INI file. Is it ? Try to go with this tutorial to read and write INI files.

If you really want to go with regex give this a try:

(?:\[(?<section>.+)\]\s+(?<!\[)(?<content>.+)(?!\]))

Demo

Use this code to read and change ini file

Imports System.IO
Imports System.Text.RegularExpressions
Imports System.Collections
Imports System.Diagnostics

Public Class IniFile
    Private m_sections As Hashtable

    Public Sub New()
        m_sections = New Hashtable(StringComparer.InvariantCultureIgnoreCase)
    End Sub

    Public Sub Load(ByVal sFileName As String)
        Dim tempsection As IniSection = Nothing
        Dim oReader As New StreamReader(sFileName)
        Dim regexcomment As New Regex("^([\s]*#.*)", (RegexOptions.Singleline Or RegexOptions.IgnoreCase))
        Dim regexsection As New Regex("^[\s]*\[[\s]*([^\[\s].*[^\s\]])[\s]*\][\s]*$", (RegexOptions.Singleline Or RegexOptions.IgnoreCase))
        Dim regexkey As New Regex("^\s*([^=\s]*)[^=]*=(.*)", (RegexOptions.Singleline Or RegexOptions.IgnoreCase))
        While Not oReader.EndOfStream
            Dim line As String = oReader.ReadLine()
            If line <> String.Empty Then
                Dim m As Match = Nothing
                If regexcomment.Match(line).Success Then
                    m = regexcomment.Match(line)
                ElseIf regexsection.Match(line).Success Then
                    m = regexsection.Match(line)
                    tempsection = AddSection(m.Groups(1).Value)
                ElseIf regexkey.Match(line).Success AndAlso tempsection IsNot Nothing Then
                    m = regexkey.Match(line)
                    tempsection.AddKey(m.Groups(1).Value).Value = m.Groups(2).Value
                ElseIf tempsection IsNot Nothing Then
                    tempsection.AddKey(line)
                Else
                End If
            End If
        End While
        oReader.Close()
    End Sub

    Public Sub Save(ByVal sFileName As String)
        Dim oWriter As New StreamWriter(sFileName, False)
        For Each s As IniSection In Sections
            oWriter.WriteLine(String.Format("[{0}]", s.Name))
            For Each k As IniSection.IniKey In s.Keys
                If k.Value <> String.Empty Then
                    oWriter.WriteLine(String.Format("{0}={1}", k.Name, k.Value))
                Else
                    oWriter.WriteLine(String.Format("{0}", k.Name))
                End If
            Next
        Next
        oWriter.Close()
    End Sub

    Public ReadOnly Property Sections() As System.Collections.ICollection
        Get
            Return m_sections.Values
        End Get
    End Property

    Public Function AddSection(ByVal sSection As String) As IniSection
        Dim s As IniSection = Nothing
        sSection = sSection.Trim()
        If m_sections.ContainsKey(sSection) Then
            s = DirectCast(m_sections(sSection), IniSection)
        Else
            s = New IniSection(Me, sSection)
            m_sections(sSection) = s
        End If
        Return s
    End Function

    Public Function GetSection(ByVal sSection As String) As IniSection
        sSection = sSection.Trim()
        If m_sections.ContainsKey(sSection) Then
            Return DirectCast(m_sections(sSection), IniSection)
        End If
        Return Nothing
    End Function

    Public Function GetKeyValue(ByVal sSection As String, ByVal sKey As String) As String
        Dim s As IniSection = GetSection(sSection)
        If s IsNot Nothing Then
            Dim k As IniSection.IniKey = s.GetKey(sKey)
            If k IsNot Nothing Then
                Return k.Value
            End If
        End If
        Return String.Empty
    End Function

    Public Function SetKeyValue(ByVal sSection As String, ByVal sKey As String, ByVal sValue As String) As Boolean
        Dim s As IniSection = AddSection(sSection)
        If s IsNot Nothing Then
            Dim k As IniSection.IniKey = s.AddKey(sKey)
            If k IsNot Nothing Then
                k.Value = sValue
                Return True
            End If
        End If
        Return False
    End Function

    Public Class IniSection
        Private m_pIniFile As IniFile
        Private m_sSection As String
        Private m_keys As Hashtable

        Protected Friend Sub New(ByVal parent As IniFile, ByVal sSection As String)
            m_pIniFile = parent
            m_sSection = sSection
            m_keys = New Hashtable(StringComparer.InvariantCultureIgnoreCase)
        End Sub

        Public ReadOnly Property Keys() As System.Collections.ICollection
            Get
                Return m_keys.Values
            End Get
        End Property

        Public ReadOnly Property Name() As String
            Get
                Return m_sSection
            End Get
        End Property

        Public Function AddKey(ByVal sKey As String) As IniKey
            sKey = sKey.Trim()
            Dim k As IniSection.IniKey = Nothing
            If sKey.Length <> 0 Then
                If m_keys.ContainsKey(sKey) Then
                    k = DirectCast(m_keys(sKey), IniKey)
                Else
                    k = New IniSection.IniKey(Me, sKey)
                    m_keys(sKey) = k
                End If
            End If
            Return k
        End Function

        Public Function GetKey(ByVal sKey As String) As IniKey
            sKey = sKey.Trim()
            If m_keys.ContainsKey(sKey) Then
                Return DirectCast(m_keys(sKey), IniKey)
            End If
            Return Nothing
        End Function

        Public Class IniKey
            Private m_sKey As String
            Private m_sValue As String
            Private m_section As IniSection
            Protected Friend Sub New(ByVal parent As IniSection, ByVal sKey As String)
                m_section = parent
                m_sKey = sKey
            End Sub
            Public ReadOnly Property Name() As String
                Get
                    Return m_sKey
                End Get
            End Property

            Public Property Value() As String
                Get
                    Return m_sValue
                End Get
                Set(ByVal value As String)
                    m_sValue = value
                End Set
            End Property

        End Class
    End Class
End Class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM