String umformen

  • Hi,

    lange nix mehr gemacht und alles verlernt. :thumbdown:
    Ich habe folgenden String (aus einer XML).

    <version>XYZ</version>

    Wobei "XYZ" variabel ist (beliebige Zeichen, beliebig oft), "<version>" und "</version>" ist immer gleich.

    Ziel der Aktion: Den variablen Teil isolieren und zwar ohne Array.
    _Stringbetween fällt damit raus, Stringregexp auch wobei ich eigentlich dachte damit könnte man den "Match" Teil auch ohne Array ausgeben? Nur wie? Alles verlernt ... :S
    Nochmal als Code was ich machen will:

    [autoit]


    dim $s_xmlline=<version>XYZ</version>
    dim $s_match=_Stringtransform($s_xmlline) ; bei dem Teil steh ich auf dem Schlauch ...
    msgbox(0, "Hallo Welt", $s_match) ; und dort sollte dann XYZ drin stehen ^^

    [/autoit]


    Gruß und danke

    Nuts

    3 Mal editiert, zuletzt von nuts (10. Januar 2015 um 00:07)

  • Wo ist denn dein Problem mit Array?
    Welche Begründung liegt denn dem zu Grunde?

    Einfach nur einen Index dran und gut:

    [autoit]

    #include <String.au3>
    Global $s_xmlline="<version>XYZ</version>"
    msgbox(0, "Hallo Welt", _StringBetween($s_xmlline, "<version>", "</version>")[0])

    [/autoit]


    Klar kannst du auch mit StringInStr und StringMid arbeiten.
    Aber allein diese Vorgabe "kein Array" ist schon so skurril, dass ich das einfach ignorieren muss.

  • Mit einem Array muss ich nach jedem _Stringbetween ein Errorhandling einbauen vor dem Zugriff auf das Array (sonst crash).
    Im eigentlichen Skript sind natürlich mehrere Zeile auszuwerten und das ist dann schon aufwendig wenn ich nach jeder Zeile ein Errorhandling brauche

    Zitat

    <version>XYZ</version>
    <version1>XYZ</version1>
    <version2>XYZ2</version2>
    <version3>XYZ3</version3>
    <version4>XYZ4</version4>
    usw.

    Wenn die Auswertung etwas nicht brauchbares ergibt (z.B. Syntaxfehler in der XML => kein Array _StringBetween) kann ich dies leicht an anderer Stelle abfangen. Dort muss auf den variablen Teil eh nochmal prüfen, da auch Unsinn in der XML stehen kann.

  • Öhm ja und wozu wurden Funktionen erfunden? Wo ist das Problem dir eine Funktion zu schreiben die ein "sicheres" stringbetween durchführt. Du brauchst dein Errorhandling nur einmalig in dieser Funktion, unabhängig davon wieviele Strings du damit nun zerlegst. Als Rückgabewert gibts du dann einen String aus und brauchst dir im eigentliche Code keine Gedanken mehr machen wegen fehlerhaften Array Zugriffen.

  • Dann schau doch einfach in die string.au3 und nutze eine modifizierte _stringbetween() Funktion die dir das zurückgibt was du willst.

    [autoit]


    Func _MyStringBetween($s_String, $s_Start, $s_End, $v_Case = -1)

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

    ; Set case type
    Local $s_case = ""
    If $v_Case = Default Or $v_Case = -1 Then $s_case = "(?i)"

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

    ; Escape characters
    Local $s_pattern_escape = "(\.|\||\*|\?|\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)"
    $s_Start = StringRegExpReplace($s_Start, $s_pattern_escape, "\\$1")
    $s_End = StringRegExpReplace($s_End, $s_pattern_escape, "\\$1")

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

    ; If you want data from beginning then replace blank start with beginning of string
    If $s_Start = "" Then $s_Start = "\A"

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

    ; If you want data from a start to an end then replace blank with end of string
    If $s_End = "" Then $s_End = "\z"

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

    Local $a_ret = StringRegExp($s_String, "(?s)" & $s_case & $s_Start & "(.*?)" & $s_End, 3)

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

    If @error Then Return SetError(1, 0, 0)
    Return $a_ret[0] ; <----------- gibt kein array mehr zurück, sondern den ersten Treffer im Array
    EndFunc ;==>_StringBetween

    [/autoit]
  • Versuches es mal damit:

    [autoit]

    StringRegExpReplace($s_xmlline, "(?im).*>(.+)<\/.*", "$1")

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Mit einem Array muss ich nach jedem _Stringbetween ein Errorhandling einbauen vor dem Zugriff auf das Array (sonst crash).


    Wenn die Funktion crasht muss der Eingabestring schon falsch sein. Also liegt der Fehler schon vor dem Aufruf begründet.
    Wenn du eine Lösung ohne Array haben willst entbindet dich das doch genauso nicht vom Error-Handling.
    Deren Ergebnisse wären ebenso Schrott wie die Array-Lösung.

    Auch wenn ich immer noch nicht nachvollziehen kann warum es unbedingt "ohne Arrays" gehen muss hier zwei mögliche Lösungen:

    [autoit]

    StringMid($s_xmlline, StringInStr($s_xmlline, "<version>") + 9, StringInStr($s_xmlline, "</version>", 2, -1) - StringInStr($s_xmlline, "<version>") - 9 )

    [/autoit][autoit]

    StringRegExpReplace($s_xmlline, "<version>(.+?)</version>", "$1")

    [/autoit]

    Edit: Hast du deinen Post bezüglich StringRegExReplace editiert?

  • Den Eingabestring kann ich nicht kontrollieren.

    Mit Array

    [autoit]

    $a_between=_Stringbetween( )
    if not @error then $s_ergebnis= $a_between[0]
    if $s_ergebnis=sinnvoll then mache dies und das

    [/autoit]

    Ohne Array

    [autoit]

    S_ergebnis=StringRegExpReplace($s_xmlline, "(?im).*>(.+)<\/.*", "$1")
    if $s_ergebnis=sinnvoll then mache dies und das

    [/autoit]

    In dem Fall lass ich das Ergebnis sogar erstmal auf eine andere Funktion los und mache dahinter das Errorhandling, da der Fehlerfall (hoffentlich) sehr selten ist.
    Ich möchte trotzdem nicht auf ein Array zugreifen ohne Prüfung und mir die gern für 99,9% der Fälle sparen (=> kein Array :D ).
    Mag kein guter Stil sein, aber für mich okay ...

    UEZ: Danke! Das funktioniert. :)
    BugFix : Wie suche ich denn nach sowas im Forum? :(