Jump to content

How to easy read KeyValues text file format?


Nubie
 Share

Go to solution Solved by Melba23,

Recommended Posts

I have some text files with KeyValues format, example

"section1"
{
    "key1"    "value1"
    "section2"
    {
        "key2"    "value2"
    }
}

I don't know how to easy get value of sections or keys. I hope have any func can easy read it like IniRead. This format at here: https://developer.valvesoftware.com/wiki/KeyValues_class

Can't use StringInStr because it can reapeat strings, example

"rarities"
    {
        "default"
        {
            "value"     "0"
            "loc_key"       "1"         
        }
        "common"
        {
            "value"     "0"
            "loc_key"       "1"         
        }
    } 

Someone please help me. Thanks :)

 

Link to comment
Share on other sites

use

InIReadSection

It will give you the key and value, a 2 dimensional array where element[n][0] is the key and element[n][1] is the value.

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

Thanks! I have understand your said, example

 

Local $var = IniReadSection(@ScriptDir & "test.ini", "Section1")

For $i = 1 To $var[0][0]
MsgBox(4096, "", "Key: " & $var[$i][0] & @CRLF & "Value: " & $var[$i][1])
Next

But it's not really what I want. I want read the text file with format I said

Link to comment
Share on other sites

So, you essentially want to mirror your text file?

Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Link to comment
Share on other sites

  • Moderators
  • Solution

Nubie,

This might do the trick: ;)

#include <StringConstants.au3>
#include <Array.au3>

$sText = _
    '"rarities"' & @CRLF & _
    '    {' & @CRLF & _
    '        "default"' & @CRLF & _
    '        {' & @CRLF & _
    '            "value"     "0"' & @CRLF & _
    '            "loc_key"       "1"' & @CRLF & _
    '        }' & @CRLF & _
    '        "common"' & @CRLF & _
    '        {' & @CRLF & _
    '            "value"     "2"' & @CRLF & _
    '            "loc_key"       "3"' & @CRLF & _
    '        }' & @CRLF & _
    '    }'

; ########################################################################################

; Parse the file into an array

$aKey_Value = _ParseFile($sText)

; Extract a value
$sKey = '"rarities"\"default"\"loc_key"'

$sRet = _ReturnValue($sKey)

MsgBox($MB_SYSTEMMODAL, "Value", $sRet)

; ########################################################################################

Func _ParseFile($sText)

        Local $aKey_Value[1][2] = [[0]]

    $aArray = StringSplit($sText, @CRLF, $STR_ENTIRESPLIT)

    $sParent = ""

    For $i = 0 To $aArray[0]

        $sLine = $aArray[$i]

        StringReplace($sLine, '"', "")
        Switch @extended
            Case 0
                ; Up/down a level
                Switch StringStripWS($sLine, $STR_STRIPALL)
                    Case "{" ; Up a level
                        $sParent &= "\"
                    Case "}" ; Down a level
                        $sParent = StringRegExpReplace($sParent, "(^.*\\)(.*\\)", "$1")
                EndSwitch

            Case 2
                ; Path element
                $sParent &= StringStripWS($sLine, $STR_STRIPALL)

            Case 4
                ; Key/value pairing
                $aPairing = StringRegExp($sLine, '(?U)(".*")', 3)

                ; Increase array size
                $aKey_Value[0][0] += 1
                ReDim $aKey_Value[$aKey_Value[0][0] + 1][2]
                ; Add data
                $aKey_Value[$aKey_Value[0][0]][0] = $sParent & $aPairing[0]
                $aKey_Value[$aKey_Value[0][0]][1] = $aPairing[1]

        EndSwitch
    Next

    _ArrayDisplay($aKey_Value, "Final", Default, 8)

    Return $aKey_Value

EndFunc

Func _ReturnValue($sKey)

    $iIndex = _ArraySearch($aKey_Value, $sKey, 1)
    If Not @error Then
        Return $aKey_Value[$iIndex][1]
    Else
        Return "Error"
    EndIf
EndFunc
M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Nubie,

Glad I could help. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 2 months later...

excuse me, I have bother again.

How can list keys having in path. Example: if path is "rarities", it'll show list "default", "common" .If path is "rarities""default", it'll show list "value", "loc_key"

Link to comment
Share on other sites

  • Moderators

Nubie,

Not too hard: ;)

#include <StringConstants.au3>
#include <Array.au3>

$sText = _
        '"rarities"' & @CRLF & _
        '    {' & @CRLF & _
        '        "default"' & @CRLF & _
        '        {' & @CRLF & _
        '            "value"     "0"' & @CRLF & _
        '            "loc_key"       "1"' & @CRLF & _
        '        }' & @CRLF & _
        '        "common"' & @CRLF & _
        '        {' & @CRLF & _
        '            "value"     "2"' & @CRLF & _
        '            "loc_key"       "3"' & @CRLF & _
        '        }' & @CRLF & _
        '    }'

; ########################################################################################

; Parse the file into an array

$aKey_Value = _ParseFile($sText)

_ArrayDisplay($aKey_Value, "Read", Default, 8)

$aMatch = _GetChildren('"rarities"', $aKey_Value)
_ArrayDisplay($aMatch, '"rarities"', Default, 8)

$aMatch = _GetChildren('"rarities"\"default"', $aKey_Value)
_ArrayDisplay($aMatch, '"rarities"\"default"', Default, 8)

; ########################################################################################

Func _GetChildren($sPath, $aKey_Value)

    ; Create array to hold children with counter
    Local $aMatch[UBound($aKey_Value)], $iCount = 0
    ; Loop through the passed array
    For $i = 1 To $aKey_Value[0][0]
        ; If the path is found in the array, extract the next item (note the need to escape the "\" character)
        $aRet = StringRegExp($aKey_Value[$i][0], "(?U)" & StringReplace($sPath, "\", "\\") & "\\(.*)(?:\\|\z)", 3)
        If Not @error Then
            ; Check if item is already in match array
            _ArraySearch($aMatch, $aRet[0])
            If @error Then
                ; and add if not
                $aMatch[$iCount] = $aRet[0]
                $iCount += 1
            EndIf
        EndIf
    Next
    ; Remove blanks from match array
    ReDim $aMatch[$iCount]

    Return $aMatch

EndFunc   ;==>_GetChildren


Func _ParseFile($sText)

    Local $aKey_Value[1][2] = [[0]]

    $aArray = StringSplit($sText, @CRLF, $STR_ENTIRESPLIT)

    $sParent = ""

    For $i = 0 To $aArray[0]

        $sLine = $aArray[$i]

        StringReplace($sLine, '"', "")
        Switch @extended
            Case 0
                ; Up/down a level
                Switch StringStripWS($sLine, $STR_STRIPALL)
                    Case "{" ; Up a level
                        $sParent &= "\"
                    Case "}" ; Down a level
                        $sParent = StringRegExpReplace($sParent, "(^.*\\)(.*\\)", "$1")
                EndSwitch

            Case 2
                ; Path element
                $sParent &= StringStripWS($sLine, $STR_STRIPALL)

            Case 4
                ; Key/value pairing
                $aPairing = StringRegExp($sLine, '(?U)(".*")', 3)

                ; Increase array size
                $aKey_Value[0][0] += 1
                ReDim $aKey_Value[$aKey_Value[0][0] + 1][2]
                ; Add data
                $aKey_Value[$aKey_Value[0][0]][0] = $sParent & $aPairing[0]
                $aKey_Value[$aKey_Value[0][0]][1] = $aPairing[1]

        EndSwitch
    Next

    Return $aKey_Value

EndFunc   ;==>_ParseFile
As always, please ask if you have any questions. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Nubie,

Glad I could help. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 1 year later...
; a few changes in the Func _ParseFile($sText)
; Change 1
  ;Local $aKey_Value[1][2] = [[0]]
  Local $iArraySize = 70000 ; Manual ArraySize
  Local $aKey_Value[$iArraySize][2] = [[0]]
; Change 2
  ; Increase array size
  $aKey_Value[0][0] += 1
  ;ReDim $aKey_Value[$aKey_Value[0][0] + 1][2]

The ReDim function is taking a lot of time.. The above code works faster.

Link to comment
Share on other sites

1 hour ago, pluto41 said:
; a few changes in the Func _ParseFile($sText)
; Change 1
  ;Local $aKey_Value[1][2] = [[0]]
  Local $iArraySize = 70000 ; Manual ArraySize
  Local $aKey_Value[$iArraySize][2] = [[0]]
; Change 2
  ; Increase array size
  $aKey_Value[0][0] += 1
  ;ReDim $aKey_Value[$aKey_Value[0][0] + 1][2]

The ReDim function is taking a lot of time.. The above code works faster.

woot, it's very fast, thanks very much :)

Link to comment
Share on other sites

I suggest to solve this way:

Func _ParseFile($sText)

    $aArray = StringSplit($sText, @CRLF, $STR_ENTIRESPLIT)
    Local $aKey_Value[UBound($aArray)-1][2] = [[0]]     ;declare array with max. needed size

    $sParent = ""

    For $i = 0 To $aArray[0]

        $sLine = $aArray[$i]

        StringReplace($sLine, '"', "")
        Switch @extended
            Case 0
                ; Up/down a level
                Switch StringStripWS($sLine, $STR_STRIPALL)
                    Case "{" ; Up a level
                        $sParent &= "\"
                    Case "}" ; Down a level
                        $sParent = StringRegExpReplace($sParent, "(^.*\\)(.*\\)", "$1")
                EndSwitch

            Case 2
                ; Path element
                $sParent &= StringStripWS($sLine, $STR_STRIPALL)

            Case 4
                ; Key/value pairing
                $aPairing = StringRegExp($sLine, '(?U)(".*")', 3)

                ; Increase array size
                $aKey_Value[0][0] += 1
                ; Add data
                $aKey_Value[$aKey_Value[0][0]][0] = $sParent & $aPairing[0]
                $aKey_Value[$aKey_Value[0][0]][1] = $aPairing[1]

        EndSwitch
    Next
    ReDim $aKey_Value[$aKey_Value[0][0] + 1][2] ;shortens the array to realy needed size

    Return $aKey_Value

EndFunc   ;==>_ParseFile

it's no so fast than @pluto41's solution, but faster than @Melba23's. If you have very big data (more than 70000 rows in $aKey_Value) pluto41's script crashes. As there is only one Redim used it's a little bit slower than pluto41's script. 

Link to comment
Share on other sites

  • Moderators

Nubie,

The usual solution to reduce the number of ReDims is to resize the array as required - look for the <<<< lines:

#include <StringConstants.au3>
#include <Array.au3>

$sText = FileRead("items.txt")

; Parse the file into an array

$aKey_Value = _ParseFile($sText)

Func _ParseFile($sText)

    Local $aKey_Value[1000][2] = [[0]] ; Set a sensible start value <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    $aArray = StringSplit($sText, @CRLF, $STR_ENTIRESPLIT)

    $sParent = ""

    For $i = 0 To $aArray[0]

        $sLine = $aArray[$i]

        StringReplace($sLine, '"', "")
        Switch @extended
            Case 0
                ; Up/down a level
                Switch StringStripWS($sLine, $STR_STRIPALL)
                    Case "{" ; Up a level
                        $sParent &= "\"
                    Case "}" ; Down a level
                        $sParent = StringRegExpReplace($sParent, "(^.*\\)(.*\\)", "$1")
                EndSwitch

            Case 2
                ; Path element
                $sParent &= StringStripWS($sLine, $STR_STRIPALL)

            Case 4
                ; Key/value pairing
                $aPairing = StringRegExp($sLine, '(?U)(".*")', 3)

                ; Increase array size
                $aKey_Value[0][0] += 1
                If $aKey_Value[0][0] = UBound($aKey_Value) Then
                    ReDim $aKey_Value[UBound($aKey_Value) * 2][2] ; ReDim array if required - double current size <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                EndIf
                ; Add data
                $aKey_Value[$aKey_Value[0][0]][0] = $sParent & $aPairing[0]
                $aKey_Value[$aKey_Value[0][0]][1] = $aPairing[1]

        EndSwitch
    Next

    ReDim $aKey_Value[$aKey_Value[0][0] + 1][2] ; Resize array to remove empty elements <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    _ArrayDisplay($aKey_Value, "Final", Default, 8)

    Return $aKey_Value

EndFunc

But as I see this is game-related, my interest ends here - please read the Forum rules to make sure you keep this legal.

M23

 

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...