- Offizieller Beitrag
Ich finde es schade, dass AutoIt keine Möglichkeit bietet Strings zwischen öffnendem und schließendem Zeichen ausbalanciert auszugeben.
Meine Funktion "_String_Balanced" ermöglicht das.
Bsp. "Das ist ein Mustertext (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu) das hier nicht".
Hier gibt es zwei Ausdrücke in runden Klammern
• (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu)
• (plus gekapselten Inhalt)
Mit meiner Funktion wird der Inhalt von öffnender Klammer bis zugehöriger schließender Klammer ermittelt.
Alle Klammertypen können verwendet werden '(', '{', '[', '<'. Bei den spitzen Klammern kann zusätzlich ein Tag verwendet werden, praktisch um z.B. Websiten zu parsen.
Es braucht nur der öffnende Begrenzer (plus optionalem Tag bei spitzen Klammern) angegeben werden. Das Pendant wird automatisch gebildet.
Weitere Parameter sind
[optional] Occurence - Welches Vorkommen im String soll gefunden werden. Wie bei StringInStr kann auch von hinten gesucht werden durch negative Zahl.
[optional] Offset - An welcher Position im String soll begonnen werden.
Standardmäßig sind Occurence und Offset so gesetzt, dass ein Array mit allen Vorkommen im String zurückgegeben wird. Dabei wird der String von Anfang bis Ende abgegrast.
Aber mal als Verleich, wie simpel das z.B. mit Lua geht, Variable: text, gesucht ausbalancierter Inhalt in runden Klammern:
_String_Balanced
;===============================================================================
; Function Name...: _String_Balanced
; Description.....: Ermittelt einen ausbalancierten String innerhalb folgender
; ................: Begrenzer: "()", "{}", "[]", "<abc abc>"
; ................: Tags bei spitzen Klammern sind optional,
; ................: müssen aber für öffnend und schließend identisch sein.
; Parameter(s)....: $_sStr String mit begrenztem Substring
; ................: $_sOpen Das öffnende Zeichen des Begrenzerpaares und optional der Tag '<bla'
; ................: Daraus wird automatisch der schließende Tag gebildet: 'bla>'
; .....optional...: $_iOccurence 0 (Standard) Rückgabe aller Funde als Array mit Zähler an [0].
; ................: n Beginnt am n-ten Vorkommen von $_sOpen im String.
; ................: Negative Werte zählen Vorkommen von rechts.
; ................: Occurence greift nur, wenn $_iOffset < 1.
; .....optional...: $_iOffset Position im String zum Start der Selektion.
; ................: 0 (Standard) Occurence wird verwendet.
; Return Value(s).: Erfolg: Der ermittelte String inkl. der Begrenzer.
; ................: Fehler: Leerstring @error = 1 $_sOpen beginnt nicht mit '(', '{', '[' oder '<'
; ................: @error = 2 $_sOpen nicht in $_sStr enthalten
; ................: @error = 3 $_iOccurence größer als Anzahl Begrenzer
; Author(s).......: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _String_Balanced($_sStr, $_sOpen, $_iOccurence=0, $_iOffset=0)
If Not StringInStr($_sStr, $_sOpen) Then Return SetError(2, 0, '')
Local $sTag = ''
If StringLeft($_sOpen, 1) = '<' Then
$sTag = StringTrimLeft($_sOpen, 1)
$_sOpen = '<'
EndIf
If Not StringInStr('({[<', $_sOpen) Then Return SetError(1, 0, '')
StringReplace($_sStr, $_sOpen & $sTag, $_sOpen & $sTag)
Local $iMax = @extended
If Abs($_iOccurence) > $iMax Then Return SetError(3, 0, '')
If $_iOffset < 1 Or $_iOffset = '' Then $_iOffset = 0
Local $sClose, $sPattern, $fFirst = False, $iLast, $vOut = ''
Local $countOpen = 0
If $_iOffset = 0 And $_iOccurence <> 0 Then
$_iOffset = StringInStr($_sStr, $_sOpen & $sTag, 1, $_iOccurence)
EndIf
If $_sOpen = '(' Then
$sClose = ')'
Else
$sClose = Chr(Asc($_sOpen) +2)
EndIf
Local $sEscape = ''
If StringInStr('({[', $_sOpen) Or $sClose = ')' Then $sEscape = '\'
$sPattern = $sEscape & $_sOpen & $sTag & '|' & $sTag & $sEscape & $sClose
While 1
$aMatch = StringRegExp($_sStr, $sPattern, 1, $_iOffset)
If Not @error Then
$_iOffset = @extended
If StringInStr('({[', $aMatch[0]) Or _
StringInStr('<' & $sTag, $aMatch[0]) Then
$countOpen += 1
Else
$countOpen -= 1
EndIf
If Not $fFirst Then
$iLast = $_iOffset
$fFirst = True
ContinueLoop
EndIf
$vOut &= StringMid($_sStr, $iLast, $_iOffset-$iLast-1)
If $countOpen = 0 Then ExitLoop
$iLast = $_iOffset -1
Else
ExitLoop
EndIf
Wend
If $_iOccurence = 0 Then
Local $n = 2, $match = $vOut, $aOut[2] = [1, $_sOpen & $sTag & $vOut & $sClose]
While True
$match = _String_Balanced($_sStr, $_sOpen & $sTag, $n, 0)
If Not @error Then
$aOut[0] += 1
ReDim $aOut[$aOut[0] +1]
$aOut[$aOut[0]] = $match
$n += 1
Else
Return $aOut
EndIf
WEnd
Else
Return $_sOpen & $sTag & $vOut & $sClose
EndIf
EndFunc ;==>_String_Balanced
Testskript
#include '_String_Balanced.au3'
#include <Array.au3>
$sHtml = _
'<div class="content">' & @CRLF & _
'<ul class="menu">' & @CRLF & _
'<li class="collapsed first no-dhtml "><li class="BLA"><a href="BLA.html"</a></li><a href="file-management.html" id="dhtml_menu-504">File management</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="session-management.html" id="dhtml_menu-505">Session management</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="editing.html" id="dhtml_menu-508">Editing</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="document-properties.html" id="dhtml_menu-509">Document Properties</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="searching.html" id="dhtml_menu-511">Searching</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="display.html" id="dhtml_menu-510">Display</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="macros.html" id="dhtml_menu-512">Macros</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="commands.html" id="dhtml_menu-513">Commands</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="shortcuts-run-menu.html" id="dhtml_menu-514">Shortcuts for the Run menu</a></li>' & @CRLF & _
'<li class="leaf no-dhtml active-trail"><a href="windows-dialog.html" id="dhtml_menu-515" class="active">Windows Dialog</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="gui-elements.html" id="dhtml_menu-744">GUI elements</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="switching-between-documents.html" id="dhtml_menu-745">Switching between Documents</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="languages.html" id="dhtml_menu-746">Languages</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="settings.html" id="dhtml_menu-747">Settings</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="plugins.html" id="dhtml_menu-749">Plugins</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="command-line.html" id="dhtml_menu-750">Command Line</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="control-files.html" id="dhtml_menu-751">Control files</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="shell-extension.html" id="dhtml_menu-752">Shell Extension</a></li>' & @CRLF & _
'<li class="collapsed no-dhtml "><a href="further-help.html" id="dhtml_menu-748">Further help</a></li>' & @CRLF & _
'<li class="leaf no-dhtml "><a href="upgrading.html" id="dhtml_menu-753">Upgrading</a></li>' & @CRLF & _
'<li class="leaf last no-dhtml "><a href="credits.html" id="dhtml_menu-754">Credits</a></li>' & @CRLF & _
'</ul>' & @CRLF & _
'</div>' & @CRLF
MsgBox(0, 'Test-html', 'Alle Treffer als Array')
$ret = _String_Balanced($sHtml, '<li')
_ArrayDisplay($ret)
MsgBox(0, 'Test-html', '5.tes Vorkommen -> Konsole')
$ret = _String_Balanced($sHtml, '<li', 5)
ConsoleWrite($ret & @CRLF)
MsgBox(0, 'Test-String mit "{"', 'Alle Treffer als Array')
$string = "TEST{'Klammer_1': {'Klammer_2': {'Inside_2': 'value'}},'key': {'Klammer_3': 'value'}}ENDE"
$ret = _String_Balanced($string, '{')
_ArrayDisplay($ret)
MsgBox(0, 'Test-String mit "("', 'Alle Treffer als Array')
$string = "Das ist ein Mustertext (hier ist was ich will (plus gekapselten Inhalt) das gehört auch dazu) das hier nicht"
$ret = _String_Balanced($string, '(')
_ArrayDisplay($ret)