_arraysearch: RegExp?

  • Hallo zusammen,

    ich möchte ein Array mit Wildcards durchsuchen. Geht das?
    Was bedeutet eigentlich Teilsuche, die man bei _arraysearch einstellen kann?

    LG FKFK

  • _ArrayFindAll(), _ArraySearch mit regex pattern

    Spoiler anzeigen
    [autoit]

    Dim $aIPs[5] = ["127.0.0.1", "127.0.0.1", "196.168.201.101", "196.168.201.102", "89.123.34.123"]
    #include<array.au3>

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

    $aResult = __ArrayFindAll($aIPs, "\A127.")
    _ArrayDisplay($aResult)

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

    Func __ArrayFindAll(Const ByRef $avArray, $vValue, $iStart = 0, $iEnd = 0, $iSubItem = 0)
    $iStart = __ArraySearch($avArray, $vValue, $iStart, $iEnd, $iSubItem)
    If @error Then Return SetError(@error, 0, -1)

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

    Local $iIndex = 0, $avResult[UBound($avArray)]
    Do
    $avResult[$iIndex] = $iStart
    $iIndex += 1
    $iStart = __ArraySearch($avArray, $vValue, $iStart + 1, $iEnd, $iSubItem)
    Until @error

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

    ReDim $avResult[$iIndex]
    Return $avResult
    EndFunc ;==>_ArrayFindAll

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

    Func __ArraySearch(Const ByRef $avArray, $vValue, $iStart = 0, $iEnd = 0, $iSubItem = -1)
    If Not IsArray($avArray) Then Return SetError(1, 0, -1)
    If UBound($avArray, 0) > 2 Or UBound($avArray, 0) < 1 Then Return SetError(2, 0, -1)

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

    Local $iUBound = UBound($avArray) - 1

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

    ; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(4, 0, -1)

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

    ; Search
    Switch UBound($avArray, 0)
    Case 1 ; 1D array search
    For $i = $iStart To $iEnd Step 1
    If StringRegExp($avArray[$i], $vValue, 0, 1) > 0 Then Return $i
    Next

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

    Case 2 ; 2D array search
    Local $iUBoundSub = UBound($avArray, 2) - 1
    If $iSubItem > $iUBoundSub Then $iSubItem = $iUBoundSub
    If $iSubItem < 0 Then
    ; will search for all Col
    $iSubItem = 0
    Else
    $iUBoundSub = $iSubItem
    EndIf

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

    For $j = $iSubItem To $iUBoundSub
    For $i = $iStart To $iEnd Step 1
    If StringRegExp($avArray[$i][$j], $vValue, 0, 1) > 0 Then Return $i
    Next
    Next
    Case Else
    Return SetError(7, 0, -1)
    EndSwitch

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

    Return SetError(6, 0, -1)
    EndFunc ;==>_ArraySearch

    [/autoit]


    Keine Ahnung ob du das brauchen kannst. Ist auf jeden Fall ungetestet. Hab kein AutoIt zur Hand.

  • Im Prinzip geht es dabei um ein Array mit IPs, daher passt das von dir i2c bestimmt ganz gut :) Danke!
    Noch eine Frage: Wenn ich bei diesem Array nun die IP-Adressen auch noch sortieren möchte? Wie gehe ich dabei am besten vor?

    • Offizieller Beitrag

    Dafür hatte ich mir mal eine UDF archiviert: _ArrayNaturalSort.au3 (siehe Anhang)
    Hier ein Beispiel:

    [autoit]


    #include "_ArrayNaturalSort.au3"
    Global $aIPs[5] = ["127.0.0.1", "196.168.21.101", "196.168.20.101", "196.168.201.102", "89.123.34.123"]

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

    _ArrayNaturalSort($aIPs)
    _ArrayDisplay($aIPs)

    [/autoit]
  • Das Problem ist der Vergleich ob 2 IP-Adressen größer oder kleiner sind.
    Ein direkter Vergleich mit AutoIt's "<" oder ">" führt auf einen Stringvergleich.
    Das ist hier jedoch natürlich falsch.
    Du brauchst also eine Sortierungsfunktion wo du die Vergleichsfunktion selbst festlegen kannst.
    Hier wäre so ein Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    Global $a_IPs[6] = ["10.2.0.1", "10.1.0.0", "11.13.0.0", "10.122.0.0", "10.2.1.1", "10.1.0.0"]

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

    QSort($a_IPs)
    _ArrayDisplay($a_IPs)

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

    ; original by ytwinky (http://www.autoit.de/index.php?page=Thread&threadID=537)
    Func QSort(ByRef $Feld, $l = 0, $r = Default)
    If Not IsArray($Feld) Then Return MsgBox(4099, "Fehler", "$Feld ist kein Array")
    If $r = Default Then $r = UBound($Feld) - 1
    Local $i = $l, $j = $r, $y, $x = $Feld[Int($l + $r) / 2]
    Do
    While kleiner($Feld[$i], $x)
    $i += 1
    WEnd
    While kleiner($x, $Feld[$j])
    $j -= 1
    WEnd
    If $i <= $j Then
    $y = $Feld[$i]
    $Feld[$i] = $Feld[$j]
    $Feld[$j] = $y
    $i += 1
    $j -= 1
    EndIf
    Until $i > $j
    If $l < $j Then QSort($Feld, $l, $j)
    If $i < $r Then QSort($Feld, $i, $r)
    EndFunc ;==>QSort

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

    ; Vergleich ob 2 IP-Adressen <> sind (ohne Fehlerbehandlung)
    Func kleiner($a, $b) ; testet ob $a < $b
    Local $a_IP1 = StringSplit($a, ".")
    Local $a_IP2 = StringSplit($b, ".")

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

    For $i = 1 To $a_IP1[0]
    If Int($a_IP1[$i]) > Int($a_IP2[$i]) Then Return False
    If Int($a_IP1[$i]) < Int($a_IP2[$i]) Then Return True
    Next
    Return False
    EndFunc

    [/autoit]

    Edit: Auch ne Lösung. Dafür hast du jetzt ne Erklärung warum das passiert und wie du es beheben kannst.