Frage zu Array

  • Hiho,

    ich stehe gerade vor einem Rätsel. Ich lese den Inhalt einer Webseite aus. So weit, so gut. Diese Seite enthält mehrere Container nach diesem Schema:

    Code
    <div class="verbox">
        <h3 class="ver">xxx</h3>
        <h3 class="date">yyy</h3>
        <div class='sec'>zzz</div>
    </div>

    Jetzt kann ich ja im Prinzip alles (ver, date, sec) mittels _StringBetween auslesen. Jedoch würde ich ganz gerne ein einziges Array mit drei Spalten bilden, an Stelle eines seperaten Arrays für jedes Teil.

    Das Einzige, was mich davon abhält ist die Tatsache, dass ich mir im Moment nicht ganz sicher bin, wie ich ein Array mit einer unbestimmten Menge an Zeilen definieren und jeweils um die Zeilen mit den entsprechenden drei Zeilen erweitern/füllen kann in Verbindung mit _Stringbetween.

    Zudem stellt sich mir nebenbei die Frage, ob _Stringbetween für mein Vorhaben die beste Wahl ist (u.A., weil es möglich ist, dass sec leer ist?!)

  • [autoit]

    #include <String.au3>
    #include <INet.au3>
    #include <Array.au3>

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

    Global Const $a_Pattern[3][2] = _
    [['<h3 class="ver">', '</h3>'], _
    ['<h3 class="date">', '</h3>'], _
    ['<div class="sec">', '</div>']]

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

    Global $s_Source = _INetGetSource ("http://url.de/")
    _ArrayDisplay (_foo ($s_Source, $a_Pattern))

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

    Func _foo ($s_String, $a_Pattern)
    Local $a_Return[1], $a_Between

    For $i = 0 To UBound ($a_Pattern) - 1
    $a_Between = _StringBetween ($s_String, $a_Pattern[$i][0], $a_Pattern[$i][1])
    If IsArray ($a_Between) Then
    $a_Return[$i] = $a_Between[0]
    ReDim $a_Return[$i + 1]
    EndIf
    Next
    Return $a_Return
    EndFunc

    [/autoit]

    Mit ReDim kannst du die Größe eines Arrays ändern.

    • Offizieller Beitrag

    $var: Er wollte ein 2D-Array für die Treffer ;)

    Ich hab dir mal eine recht flexible Lösung erstellt. Aber die Container müssen, nach deiner Vorgabe, immer '<div class="verbox">' heißen. Die Tags in den Containern müssen logischerweise auch identisch sein.
    Was flexibel ist:
    - es wird sowohl @CR als auch @CRLF als Zeilenumbruch erkannt
    - der Einzug kann TAB und/oder Leerzeichen enthalten
    - die Stringmarkierung erfasst einfache und doppelte Anführungszeichen

    Als Ergebnis erhältst du ein Array mit einer Zeile für jeden Container.

    Spoiler anzeigen
    [autoit]

    $s = _
    '<div class="verbox">' & @CRLF & _
    ' <h3 class="ver">xxx</h3>' & @CRLF & _
    ' <h3 class="date">yyy</h3>' & @CRLF & _
    " <div class='sec'>zzz</div>" & @CRLF & _
    '</div>' & @CRLF & _
    '<div class="verbox">' & @CRLF & _
    ' <h3 class="ver">aaa</h3>' & @CRLF & _
    ' <h3 class="date">bbb</h3>' & @CRLF & _
    " <div class='sec'>ccc</div>" & @CRLF & _
    '</div>' & @CRLF & _
    '<div class="verbox">' & @CRLF & _
    ' <h3 class="ver">111</h3>' & @CRLF & _
    ' <h3 class="date">222</h3>' & @CRLF & _
    " <div class='sec'>333</div>" & @CRLF & _
    '</div>' & @CRLF & _
    '<div class="verbox">' & @CRLF & _
    ' <h3 class="ver">444</h3>' & @CRLF & _
    ' <h3 class="date">555</h3>' & @CRLF & _
    " <div class='sec'>666</div>" & @CRLF & _
    '</div>' & @CRLF

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

    $pattern = '<div class=["|'&"'"&']verbox["|'&"'"&']>\r?\n[\t|\s]*<h3 class=["|'&"'"&']ver["|'&"'"&']>(.*)</h3>\r?\n[\t|\s]*<h3 class=["|'&"'"&']date["|'&"'"&']>(.*)</h3>\r?\n[\t|\s]*<div class=["|'&"'"&']sec["|'&"'"&']>(.*)</div>\r?\n</div>'

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

    $aRet = StringRegExp($s, $pattern, 3)
    Local $aMatch[UBound($aRet)/3][3], $j = 0
    For $i = 0 To UBound($aRet) -1 Step 3
    $aMatch[$j][0] = $aRet[$i]
    $aMatch[$j][1] = $aRet[$i +1]
    $aMatch[$j][2] = $aRet[$i +2]
    $j += 1
    Next

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

    _ArrayDisplay($aMatch)

    [/autoit]
  • Mahlzeit,

    danke für eure Vorschläge. Sieht so weit ganz gut aus, funktioniert aber leider noch nicht so ganz :)

    Was mir aufgefallen ist ist, dass nach "sec" noch ein Mal "sec" erfolgen kann. Das hab ich aber jetzt erst gesehen.

    Hier mal ein Beispiel, wie es 1:1 auf der auszulesenden Seite zu finden ist:

    Dementsprechend habe ich es erst ein Mal so probiert:

    [autoit]

    #include <Array.au3>

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

    $s = ' <div class="verbox">' & @CRLF & _
    '<h3 class="ver">Version: 1.2.3.4</h3>' & @CRLF & _
    '<h3 class="date">Released on: May 5th, 2012</h3>' & @CRLF & @CRLF & _
    '<div class=''sec''> <h4>Lorem Ipsum</h4> <p>XXXXX<br />' & @CRLF & _
    'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam.<br />' & @CRLF & _
    '<br />' & @CRLF & _
    'YYYYY<br />' & @CRLF & _
    'Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.<br />' & @CRLF & _
    '</p> </div><div class=''sec''> <h4>Lorem Ipsum</h4> <p>ZZZZZ<br />' & @CRLF & _
    'Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.<br />' & @CRLF & _
    '</p> </div> </div>'

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

    $pattern = '<div class=["|'&"'"&']verbox["|'&"'"&']>\r?\n[\t|\s]*<h3 class=["|'&"'"&']ver["|'&"'"&']>(.*)</h3>\r?\n[\t|\s]*<h3 class=["|'&"'"&']date["|'&"'"&']>(.*)</h3>\r?\n[\t|\s]*<div class=["|'&"'"&']sec["|'&"'"&']>(.*)</div>\r?\n</div>'

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

    $aRet = StringRegExp($s, $pattern, 3)
    Local $aMatch[UBound($aRet)/3][3], $j = 0
    For $i = 0 To UBound($aRet) -1 Step 3
    $aMatch[$j][0] = $aRet[$i]
    $aMatch[$j][1] = $aRet[$i +1]
    $aMatch[$j][2] = $aRet[$i +2]
    $j += 1
    Next

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

    _ArrayDisplay($aMatch)

    [/autoit]

    was wiederum den Fehler ausspuckt:

    Zitat

    AutoIt v3 Script (neu).au3 (18) : ==> Array variable subscript badly formatted.:
    Local $aMatch[UBound($aRet)/3][3], $j = 0
    Local $aMatch[^ ERROR

    Das passiert aber auch dann, wenn ich zu Testzwecken das 2. Vorkommen des "sec"-Containers entferne. Dementsprechend muss der Fehler woanders liegen, aber ich hab keine Ahnung :huh:

    Auf der auszulesenden Seite sind ca. 29 dieser Container zu finden, die allesamt grundsätzlich gleich aufgebaut sind, jedoch nicht allesamt einen 2. "sec"-Container beinhalten.