Zeilenumbruch in einer Tabelle

  • Hallo,
    ich habe ein Problem mit dem Aufbau einer Tabelle und der Aufteilung eines Textest in zwei Zeilen. Ich würde gern den Inhalt von $aResult[0][2] auf zwei Zeilen aufteilen wollen. So das sich das folgende Bild ergeben würde:

    223-223-9993-9980-229 Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! .....Hier noch ein weiterer Text der auch etwas länger sein kann
    Aber soll hier rein am besten auf die zweite Zeile!

    Hat jemand eine Idee wie ich das am einfachsten realisieren könnte.

    Gruß Ingo

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #Include <GuiButton.au3>

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

    Local $aResult[1][3]
    Local $sGUIEditInhalt
    Local $iLen
    Local $iDescriptionLen
    Local $iAbstand = 2

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

    $GUI_Tabelle = GUICreate("Tabelle",1122,655,-1,-1,-1,-1)
    $GUICtrlButtonExit = GUICtrlCreateButton("Exit",1001,574,100,30,-1,-1)
    $GUIEdit = GUICtrlCreateEdit("",20,10,1081,530,-1,-1)
    GUICtrlSetFont(-1,5,400,0,"Courier")
    GUISetState(@SW_SHOW,$GUI_Tabelle)

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

    $aResult[0][0] = "Hier noch ein weiterer Text der auch etwas länger sein kann"
    $aResult[0][1] = "223-223-9993-9980-229"
    $aResult[0][2] = "Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! Aber soll hier rein am besten auf die zweite Zeile!"

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

    For $i = 0 To UBound($aResult) - 1
    If StringLen($aResult[$i][1]) > $iLen Then $iLen = StringLen($aResult[$i][1]) ;nax Länge IP ermitteln
    If StringLen($aResult[$i][2]) > $iDescriptionLen Then $iDescriptionLen = StringLen($aResult[$i][2]) ;max. Länge Beschreibung ermitteln
    Next

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

    For $i = 0 To UBound($aResult) - 1
    $sGUIEditInhalt = $sGUIEditInhalt & StringFormat("%-" & $iLen + $iAbstand & "s", $aResult[$i][1]) & _
    StringFormat("%-" & $iDescriptionLen + $iAbstand & "s", $aResult[$i][2]) & _
    $aResult[$i][0] & @CRLF
    Next

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

    GUICtrlSetData($GUIEdit, $sGUIEditInhalt, 1)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $GUICtrlButtonExit
    Exit
    EndSwitch
    WEnd

    [/autoit]
  • Ich weiß nicht, wo mein Beitrag von ca. 2:00 Uhr MEZ geblieben ist, aber dann hier mein neuer Beitrag und gleich mit drei Lösungsansätzen.

    Alle vier Lösungsansätze sind sehr gut in der Hilfe erklärt.

    Spoiler anzeigen
    [autoit]


    #include <String.au3>

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

    ; String wird für alle Beispiel angewendet
    $Text = "223-223-9993-9980-229 Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! .....Hier noch ein weiterer Text der auch etwas länger sein kann Aber soll hier rein am besten auf die zweite Zeile!"

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

    ;Bsp.-1
    Local $result = StringLeft($Text, 22) ; Text von links
    Local $result2 = StringRight($Text, 208) ; Text von rechts
    MsgBox(0, "StringLeft / Zahlekombi: ", $result)
    MsgBox(0, "StringRight / Text: ", $result2)

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

    ;Bsp.-2
    Local $var = StringMid($Text, 1, 22); Text von links in Länge 22 ab Pos. 1
    Local $var2 = StringMid($Text, 23, 230); Text von links in Länge 230 ab Pos. 23
    MsgBox(0, "StringMid 1", $var)
    MsgBox(0, "StringMid 2", $var2)

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

    ;Bsp.-3
    $StEx = _StringExplode($Text, " " , "1"); String nach dem ersten Leerzeichen trennen
    MsgBox(0,"mit _StringExplode","Teil 1: " & $StEx[0] & " und Teil 2: " & $StEx[1])

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

    ;Bsp.-4
    Local $result1 = StringTrimRight($Text, 208); Text von rechts um 22 Zeichen gekürzt
    Local $result2 = StringTrimLeft($Text, 22); Text von links um 22 Zeichen gekürzt
    MsgBox(0, "StringTrimRight/Left" ,"Erster Teil: " & $result1 & " ,das war eine Zahlekombi und nun der Text: " & $result2)

    [/autoit]

    Bsp.-3 zeigt Dir auch den Ansatz, wie Du den langen Text in z. B. drei Zeilen aufteilen kannst.
    Bsp.-1 und 2 arbeiten ja mit festen Längenwerten. Bei Bsp.-3 arbeitet man mit dem Delimiter/Trennzeichen
    zum teilen des Textes. Nur Mußt Du da dann die Ergebnisse aneinander fügen (Bsp.: $StEx[6] & $StEx[7] & $StEx[8] & $StEx[9]).
    Ob man sagen kann "aneinader fügen von $StEx[6] bis $StEx[9]", das kann ich so nicht sagen. Wird aber sichrlich noch jemand Stellung zu nehmen.

    Edit: so oft, weil ich Fehler nicht mag, die ich in meinen Texten erkenne. ;) Berufskrankheit !!! ;)

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    6 Mal editiert, zuletzt von Alina (3. Dezember 2014 um 05:40)

  • Hallo Alina,
    vielen Dank für deine schnelle Antwort. Ich glaube die Aufteilung am Trennzeichen werde ich wohl aufgreifen und mit StringSplit($text, " ") den Text in eingelne Worte zerlegen und danach neu zusammen setzen.

    Gruß Ingo

  • Hallo Ingo.

    Sehe dir mal die "String" Sachen in der Hilfe durch. Evtl. findest Du noch was, das dir danach noch weiter hilft. Die SuFu & Hilfe sid auch so gut mal durchzuschauen, man lernt daraus auch viel.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    Einmal editiert, zuletzt von Alina (3. Dezember 2014 um 20:35)

  • Hallo,
    ich habe mal etwas zusammen gebaut. Ist zwar noch nicht wirklich optimal aber ein Anfang. Eventuell werde ich noch etwas erweitern, so dass er auch andere Sonderzeichen als Trennstelle akzeptiert. Im Moment trennt er einfach im Word wenn er kein Leerzeichen findet.

    Gruß Ingo

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    Global $TEMP
    Global $sLangerText

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

    $sLangerText = "Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! Aber der soll hier rein und am besten auf die zweite Zeile!"

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

    $TEMP = LineBreak($sLangerText, 30, 40)

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

    _ArrayDisplay($TEMP)

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

    Func LineBreak($sText, $iLengthMin, $iLengthMax)
    Local $aReturn[1]
    Local $sZwischenMinUndMax
    Local $sTeilString
    Local $iPosTrennzeichen
    Local $iDifferenzLengthMinMax = $iLengthMax - $iLengthMin

    ;wenn der Text kürzer ist als die max. Länge zurück springen
    If StringLen ( $sText) <= $iLengthMax Then
    $aReturn[0] = 1
    _ArrayAdd($aReturn, $sTeilString)
    Return $aReturn
    EndIf

    While 1
    $sZwischenMinUndMax = StringMid($sText, $iLengthMin, $iDifferenzLengthMinMax) ;den möglichen Bereich extrahieren
    $iPosTrennzeichen = StringInStr(StringReverse($sZwischenMinUndMax), " ") ;in möglichen Bereich nach einem Trennzeichen suchen
    $sTeilString = StringLeft($sText, $iLengthMax - $iPosTrennzeichen) ;den ermitteltet Text extrahieren

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

    _ArrayAdd($aReturn, StringStripWS($sTeilString, 3)) ;und in einem Array ablegen
    $aReturn[0] = $aReturn[0] + 1

    $sText = StringTrimLeft($sText, $iLengthMax - $iPosTrennzeichen) ;jetzt den verarbeiteten Bereich aus dem Ausgangstext löschen

    ;wenn nur noch der letzten Teil übrig den noch einfügen und zurück
    If StringLen($sText) <= $iLengthMax Then
    _ArrayAdd($aReturn, StringStripWS($sText, 3))
    $aReturn[0] = $aReturn[0] + 1
    Return $aReturn
    EndIf
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Hi,
    ohne Array, wenn man eins benötigt, hilft StringSplit()

    [autoit]

    #include <Array.au3>

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

    Global $TEMP
    Global $sLangerText

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

    $sLangerText = "Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! Aber der soll hier rein und am besten auf die zweite Zeile!"

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

    $TEMP = LineBreak($sLangerText, 40)
    MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @LF & '$TEMP' & @LF & @LF & 'Return:' & @LF & $TEMP) ;### Debug MSGBOX

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

    Func LineBreak($sText, $iLengthMax,$replace = @CRLF)
    $sText_ret = "" ;returnstring
    $pos = 1 ;Startposition für den $iLengthMax langen String im Text
    Do
    $mid = StringMid($sText, $pos, $iLengthMax) ;Text-Block
    If StringLen($mid) < $iLengthMax Then $replace = " " ;letzte Zeile, dann Leerzeichen nicht ersetzen
    $sText_ret = $sText_ret & StringReplace($mid, " ", $replace, -1) ;letztes Leerzeichen im Block ersetzen
    $pos = $pos + $iLengthMax ;nächster Block
    Until $mid = "" ;so lange, bis kein Block mehr vorhanden ist

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

    Return $sText_ret
    EndFunc ;==>LineBreak

    [/autoit]
  • Wer es bisschen kompakter mag:

    [autoit]

    Global $sLangerText = "Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! Aber der soll hier rein und am besten auf die zweite Zeile!"

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

    Global $TEMP = StringRegExpReplace($sLangerText, "(.{1,40})(?<=\s|$)", "$1" & @CRLF)
    MsgBox(0, "", $TEMP)

    [/autoit]
  • Moin AspirinJunkie.

    Mit den StringRegExpReplace und den Pattern tue ich mich schon bei dem verstehen schwer. Habe es mal

    Patternerklärung so ???

    Spoiler anzeigen

    (
    . Findet jedes einzelne Zeichen (außer Zeilenumbrüche).
    {1,40} Wiederholt die bisherigen Zeichenmindestens 1mal und maximal inklusive 40 mal.
    )
    (
    ?= prüft, was vor der Übereinstimmung stehen darf.
    \ "escapen" o. "maskieren").
    s Findet alle Leerzeichentypen: Chr(9) bis Chr(13), welche Tabulator, Zeilenschaltung, senkrechter Tab, Seitenvorschub, Wagenrücklauf und das Leerzeichen sind ( Chr(32)
    | Oder. Der Ausdruck auf der einen Seite oder auf der anderen Seite wird gefunden.
    $ Findet ein Zeilenende innerhalb der Datenmenge.
    )

    Zum Verständnis für mich bzw. Frage: Bedeutet {1,40} nun, das er das 1. bis 40, Zeichen das er findet an $TEMP ab gibt, als $1, dann setzt er ein @CRLF und sucht weiter 41-81, usw. und wenn keine 40 mehr zusammen kommen ($ hat ja das Zeilenende gefunden), dann "fertig" mit $Temp füllen! Richtig?

    Ich habe einfach das Problem, das ich nicht weiß, wie ich im Kopf denken muss, mir die richtige Frage die zu lösen für stellen kann, damit ich endlich mal verstehe, wie das pattern funktioniert. :(

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Eigentlich war deine Patternerklärung schon gar nicht mal so schlecht.
    Ich versuche es dennoch mal bisschen anders zu erklären:

    .{1,40} findet eine Kette aus beliebigen Zeichen. Diese ist mindestens 1 Zeichen lang aber maximal 40 Zeichen.
    Wichtig ist dabei zu wissen das RegEx standardmäßig gierig arbeitet. Es versucht also immer erst einmal so viel wie möglich zu finden. In unserem Falle also 40 Zeichen.
    Er fängt also an zu suchen und probiert die ersten 40 Zeichen: "Ein sehr langer Text mit vielen Zeichen ".
    In dem Fall schonmal ganz gut um danach einen Zeilenumbruch zu setzen.
    Also geht es weiter - die nächsten 40 Zeichen: "und vielen Worten der nicht so richtig p". Hier passt es schon nicht mehr, da die 40 Zeichen mitten in einem Wort aufhören.
    Wir möchten daher sagen: Ok. Versuche bis 40 Zeichen soviel wie möglich zu finden aber es muss mit einem vollständigen Wort enden.
    Was kommt nach einem Wort im normalen Text? - genau - ein Leerzeichen.
    Und genau diese Aufgabe übernimmt der Teil (?<=\s|$). Das bedeutet, dass das was davor steht nur matcht, wenn danach direkt ein Leerzeichen oder das Stringende steht.
    Heißt also: Er fängt erst immer mit 40 Zeichen an und wenn danach kein Leerzeichen kommt, versucht er es ob die Bedingung bei 39 Zeichen klappt, wenn nicht bei 38... etc...

    Die Klammer um .{1,40} ist nur dafür da, dass dieser Teil gruppiert wird und man beim Ersetzen per $1 wieder darauf zugreifen kann.

  • Hi,
    ja, am RegEx hatte ich auch rumgefummelt, aber sehr schnell gemerkt, dass die in AutoIt implementierte Engine eine Ausnahme darstellt bei der Behandlung von "Lookbehinds"
    Bei den von mir getesteten online-Testern war keiner in der Lage, den von AspirinJunkie erstellten Pattern fehlerfrei auszuführen!

    http://www.regular-expressions.info/lookaround.html

    Der 2.Abschnitt in Important Notes About Lookbehind

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (7. Dezember 2014 um 16:08)

  • Ich würde nicht sagen, das PCRE eine Ausnahme darstellt bei der Behandlung von Lookarounds.
    Das Pattern (mit Anpassung an die jeweilige Syntax) sollte genauso mit z.B. C#, VB, Ruby, PHP, Java und R laufen.
    Lediglich Javascript, Python und Perl (von den größeren Enginges) machen da nicht mit.

    Wenn es aber ein Pattern sein soll, welches universell läuft (wieder auf entsprechende Syntax achten) dann kann man das ganze natürlich noch entsprechend simplifizieren:

    [autoit]

    Global $sLangerText = "Ein sehr langer Text mit vielen Zeichen und vielen Worten der nicht so richtig passen will! Aber der soll hier rein und am besten auf die zweite Zeile!"
    Global $TEMP = StringRegExpReplace($sLangerText, "(.{1,40})(?:\s|$)", "$1" & @CRLF)
    MsgBox(0, "", $TEMP)

    [/autoit]