Stringbearbeitung mit Python-Syntax

    • Offizieller Beitrag

    Hi,
    ich habe mal ein wenig in der Python-Syntax "fremdgeschnüffelt" :D und finde die dortige Syntax zur Stringbearbeitung sehr komfortabel. Unsere Befehle StringLeft, -Right, -Mid, -TrimLeft, -TrimRight sind alle in einer simplen Syntax enthalten.

    Spoiler anzeigen
    Code
    Stringvariable[Maske]
    Maske:
    Index ist 0-basiert
    i		Zeichen an Index (i)
    i:j		String zwischen Index (i) und Index (j), inkl.(i)
    :i		String zwischen Anfang und Index (i)
    i:		String ab Index (i) bis Ende
    -n		das n-te Zeichen von rechts
    -n:		die letzten n Zeichen
    :-n		alles außer den n letzten Zeichen


    Das ist recht angenehm zu händeln. Also habe ich es mal für AutoIt analog umgesetzt. Vielleicht findet jemand Geschmack dran. ;)

    Spoiler anzeigen
    [autoit]

    $s = '0123456789'
    ConsoleWrite('> String gesamt ' & $s & @CRLF)
    ConsoleWrite('> Das 2-te Zeichen ' & _StrPython($s, '1') & @CRLF)
    ConsoleWrite('> an Index 2 bis 5 ' & _StrPython($s, '2:6') & @CRLF)
    ConsoleWrite('> bis Index 6 ' & _StrPython($s, ':6') & @CRLF)
    ConsoleWrite('> alles ab Index 6 ' & _StrPython($s, '6:') & @CRLF)
    ConsoleWrite('> 2-tes von rechts ' & _StrPython($s, '-2') & @CRLF)
    ConsoleWrite('> die letzten 3 ' & _StrPython($s, '-3:') & @CRLF)
    ConsoleWrite('> außer letzte 3 ' & _StrPython($s, ':-3') & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _StrPython($sString, $sMask)
    Local $aMask = StringSplit($sMask, ':', 2)
    Select
    Case StringRegExp($sMask, '\A\d+\z') ; == i
    Return StringMid($sString, $sMask+1, 1)
    Case StringRegExp($sMask, '\A\d+:\d+\z') ; == i:j
    Return StringMid($sString, $aMask[0]+1, $aMask[1]-$aMask[0])
    Case StringRegExp($sMask, '\A\:\d+\z') ; == :i
    Return StringLeft($sString, $aMask[1])
    Case StringRegExp($sMask, '\A\d+:\z') ; == i:
    Return StringMid($sString, $aMask[0]+1)
    Case StringRegExp($sMask, '\A-\d+\z') ; == -n
    Return StringMid($sString, StringLen($sString)+$sMask+1, 1)
    Case StringRegExp($sMask, '\A-\d+:\z') ; == -n:
    Return StringRight($sString, Abs($aMask[0]))
    Case StringRegExp($sMask, '\A:-\d+\z') ; == :-n
    Return StringTrimRight($sString, Abs($aMask[1]))
    EndSelect
    EndFunc

    [/autoit]

    Edit:
    Ja ja - es geht natürlich auch ohne RegExp :P :

    Spoiler anzeigen
    [autoit]

    Func _StrPython($sString, $sMask)
    Local $aMask = StringSplit($sMask, ':', 2)
    If Not StringInStr($sMask, ':') Then ; == i, -n
    If $sMask < 0 Then Return StringMid($sString, StringLen($sString)+$sMask+1, 1) ; == -n
    Return StringMid($sString, $sMask+1, 1) ; == i
    ElseIf StringLeft($sMask, 1) = ':' Then ; == :i, :-n
    If $aMask[1] < 0 Then Return StringTrimRight($sString, Abs($aMask[1])) ; == :-n
    Return StringLeft($sString, $aMask[1]) ; == :i
    ElseIf StringRight($sMask, 1) = ':' Then ; == i:, -n:
    If $aMask[0] < 0 Then Return StringRight($sString, Abs($aMask[0])) ; == -n:
    Return StringMid($sString, $aMask[0]+1) ; == i:
    Else
    Return StringMid($sString, $aMask[0]+1, $aMask[1]-$aMask[0]) ; == i:j
    EndIf
    EndFunc

    [/autoit]


    Edit 16.10.2012
    Ich habe die Funktion jetzt etwas erweitert. Zusätzlich zu der bisherigen Syntax kann die Funktion jetzt mit Operationskonstanten aufgerufen werden. Das ist unter Umständen leichter zu merken.
    Weiterhin habe ich ein Skript beigefügt um UserCallTips für die Funktion zu installieren.

    StrPython v0.2
    [autoit]

    #Region - TimeStamp
    ; 2012-10-16 13:01:10 v 0.2
    #EndRegion - TimeStamp

    [/autoit] [autoit][/autoit] [autoit]

    #include-once
    Global Const $_OIx = -2000 ; == On Index
    Global Const $_FTo = $_OIx +1 ; == From (Index) To (Index)
    Global Const $_FSTo = $_OIx +2 ; == From Start To (Index)
    Global Const $_FToE = $_OIx +3 ; == From (Index) To End
    Global Const $_PFR = $_OIx +4 ; == (Char At) Position From Right
    Global Const $_ChR = $_OIx +5 ; == (Number) Chars Right
    Global Const $_WoChR = $_OIx +6 ; == Without (Number) Chars Right

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name....: _StrPython
    ; Description......: Stringbearbeitung mit Pythonsyntax
    ; Parameter(s).....: $sString der zu bearbeitende String
    ; .................: $sOp entweder Maske oder Operator Variable:
    ; .................: Maske, die die Operation definiert, Index ist 0-basiert
    ; .................: Maske OperatorVar.
    ; .................: i $_OIx Zeichen an Index (i)
    ; .................: i:j $_FTo String von Index (i) bis Index (j) , inkl. (i) / exkl. (j)
    ; .................: :i $_FSTo String ab Anfang bis Index (i) , exkl. (i)
    ; .................: i: $_FToE String ab Index (i) bis Ende , inkl. (i)
    ; .................: -n $_PFR das n-te Zeichen von rechts
    ; .................: -n: $_ChR die letzten n Zeichen
    ; .................: :-n $_WoChR alles außer den n letzten Zeichen
    ; .................: $iVal (nur bei Verwendung OperatorVar.) der (Von) Index
    ; .................: $iTo (nur bei Verwendung OperatorVar.) der Bis Index
    ; Return Value(s)..: Erfolg Das Ergebnis der Bearbeitung
    ; .................: Fehler '' und @error 1 = Von-Bis-Operation ohne Bis-Index
    ; .................: @error 2 = kein gültiger Operationstyp
    ; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
    ;===============================================================================
    Func _StrPython($sString, $sOp, $iVal='', $iTo='')
    Local $sMask = $sOp
    If $iVal <> '' Then
    Switch $sOp
    Case $_OIx ; == On Index
    $sMask = $iVal
    Case $_FTo ; == From To
    If $iTo = '' Then Return SetError(1,0,'')
    $sMask = $iVal & ':' & $iTo
    Case $_FSTo ; == From Start To
    $sMask = ':' & $iVal
    Case $_FToE ; == From To End
    $sMask = $iVal & ':'
    Case $_PFR ; == Position From Right
    $sMask = '-' & $iVal
    Case $_ChR ; == Chars Right
    $sMask = '-' & $iVal & ':'
    Case $_WoChR ; == Without Chars Right
    $sMask = ':-' & $iVal
    Case Else
    Return SetError(2,0,'')
    EndSwitch
    EndIf
    Local $aMask = StringSplit($sMask, ':', 2)
    If Not StringInStr($sMask, ':') Then ; == i, -n
    If $sMask < 0 Then Return StringMid($sString, StringLen($sString)+$sMask+1, 1) ; == -n
    Return StringMid($sString, $sMask+1, 1) ; == i
    ElseIf StringLeft($sMask, 1) = ':' Then ; == :i, :-n
    If $aMask[1] < 0 Then Return StringTrimRight($sString, Abs($aMask[1])) ; == :-n
    Return StringLeft($sString, $aMask[1]) ; == :i
    ElseIf StringRight($sMask, 1) = ':' Then ; == i:, -n:
    If $aMask[0] < 0 Then Return StringRight($sString, Abs($aMask[0])) ; == -n:
    Return StringMid($sString, $aMask[0]+1) ; == i:
    Else
    Return StringMid($sString, $aMask[0]+1, $aMask[1]-$aMask[0]) ; == i:j
    EndIf
    EndFunc ;==>_StrPython

    [/autoit]
    Beispiel
    [autoit]

    #include "StrPython.au3"

    [/autoit] [autoit][/autoit] [autoit]

    $s = '0123456789'
    ConsoleWrite('> String gesamt ' & $s & @CRLF)
    ConsoleWrite('> Das 2-te Zeichen ' & _StrPython($s, '1' ) & @CRLF)
    ConsoleWrite('> von Index 2 bis (exkl.) 6 ' & _StrPython($s, '2:6') & @CRLF)
    ConsoleWrite('> bis Index 6 (exkl.) ' & _StrPython($s, ':6' ) & @CRLF)
    ConsoleWrite('> alles ab Index 6 (inkl.) ' & _StrPython($s, '6:' ) & @CRLF)
    ConsoleWrite('> 2-tes von rechts ' & _StrPython($s, '-2' ) & @CRLF)
    ConsoleWrite('> die letzten 3 ' & _StrPython($s, '-3:') & @CRLF)
    ConsoleWrite('> außer letzte 3 ' & _StrPython($s, ':-3') & @CRLF)
    ConsoleWrite(@CRLF)
    ConsoleWrite('> String gesamt ' & $s & @CRLF)
    ConsoleWrite('> Das 2-te Zeichen ' & _StrPython($s, $_OIx, 1) & @CRLF) ; == On Index
    ConsoleWrite('> von Index 2 bis (exkl.) 6 ' & _StrPython($s, $_FTo, 2, 6) & @CRLF) ; == From (Index) To (Index)
    ConsoleWrite('> bis Index 6 (exkl.) ' & _StrPython($s, $_FSTo, 6) & @CRLF) ; == From Start To (Index)
    ConsoleWrite('> alles ab Index 6 (inkl.) ' & _StrPython($s, $_FToE, 6) & @CRLF) ; == From (Index) To End
    ConsoleWrite('> 2-tes von rechts ' & _StrPython($s, $_PFR, 2) & @CRLF) ; == (Char At) Position From Right
    ConsoleWrite('> die letzten 3 ' & _StrPython($s, $_ChR, 3) & @CRLF) ; == (Number) Chars Right
    ConsoleWrite('> außer letzte 3 ' & _StrPython($s, $_WoChR, 3) & @CRLF) ; == Without (Number) Chars Right

    [/autoit]
    Installation UserCallTips
    [autoit]

    ; == UserCallTips installieren
    $sPathUserCallTips = StringLeft(@AutoItExe, StringInStr(@AutoItExe, '\', 0, -1)) & 'SciTE\api\au3.user.calltips.api'
    $sToWrite = _
    '_StrPython ( $Str, $_OIx, INDEX ) od. ( $Str, "INDEX" ) Gibt Zeichen an Index zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_FTo, INDEX_1, INDEX_2 ) od. ( $Str, "INDEX_1:INDEX_2" ) Gibt Zeichen zw. Index_1 und (exkl.) Index_2 zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_FSTo, INDEX ) od. ( $Str, ":INDEX" ) Gibt Zeichen von Start bis (exkl.) Index zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_FToE, INDEX ) od. ( $Str, "INDEX:" ) Gibt Zeichen von Index bis Ende zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_PFR, NUMBER ) od. ( $Str, "-NUMBER" ) Gibt das n-te Zeichen von rechts zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_ChR, NUMBER ) od. ( $Str, "-NUMBER:" ) Gibt n Zeichen von rechts zurück; erfordert StrPython.au3' & @CRLF & _
    '_StrPython ( $Str, $_WoChR, NUMBER ) od. ( $Str, ":-NUMBER" ) Gibt String ohne n rechte Zeichen zurück; erfordert StrPython.au3' & @CRLF
    If Not FileExists($sPathUserCallTips) Then
    FileWrite($sPathUserCallTips, $sToWrite)
    Else
    $hFile = FileOpen($sPathUserCallTips, 1)
    FileWrite($hFile, @CRLF & $sToWrite)
    FileClose($hFile)
    EndIf

    [/autoit]
    • Offizieller Beitrag

    Nette Funktion, kommt gleich mal in meine Sammlung. :thumbup:


  • :D Ich wollte nur deine Aufmerksamkeit wecken. :rofl: - Nun auch in RegExp-freier Version. ;)


    Du schaffst es immer wieder. ;) Dieses Mal hat sich die Laufzeit halbiert.