String splitten - Problem

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von picoflop.

    String splitten - Problem

    Tach gesagt,

    vorweg: ich habe allgemein wenig Erfahrung, was das Thema Programmieren angeht - also seid bitte nicht zu streng mit mir :b


    Ausgangssituation
    Ich habe eine Textdatei (einlesen.txt) mit folgendem exemplarischen Inhalt:

    das (1)
    ist (2)
    ein
    test (4)

    Die Datei wird im gesamten eingelesen und soll anschließend bei " ( " gesplittet werden - sofern vorhanden.

    Als Ergebnis möchte ich mir SQL-Statements ausgeben lassen.
    Zum Beispiel: VALUES ('das','1') ODER (wenn nicht gesplittet wird) VALUES ('ein','')



    Nun zum eigentlichen Problem.

    Sobald das Programm in einer Zeile kein " ( " zum splitten findet, stoppt die Ausgabe in die .txt und es befinden sich NUR die Zeilen 1 + 2 in der "ausgeben.txt"

    Also:


    VALUES ('das ','1')
    VALUES ('ist ','2')


    Für die If-Else-Anweisung während der Ausgabe habe ich bereits verschiedene Wege - erfolglos - getestet.
    Also zum Beispiel String.IsNullOrEmpty; <> 0 und solche spielereien...

    Ich hoffe sehr, dass mir jemand mit dem Problem helfen kann.

    Anbei der Quellcode.

    Mit freundlichen Grüßen

    //////////CODE/////////

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    4. Dim myArray As String()
    5. Dim str As String
    6. Dim strArr() As String
    7. myArray = System.IO.File.ReadAllLines("PFAD\WindowsApplication1\bin\Debug\einlesen.txt", System.Text.Encoding.UTF8)
    8. Try
    9. For x = 0 To myArray.Count - 1
    10. str = myArray(x)
    11. strArr = str.Split(New Char() {"("c}) ' bei " ( " splitten
    12. strArr(1) = strArr(1).Substring(0, strArr.Length - 1) ' " ) " am zeilenende entfernen
    13. Dim ausgabe As System.IO.StreamWriter
    14. ausgabe = My.Computer.FileSystem.OpenTextFileWriter("PFAD\WindowsApplication1\bin\Debug\ausgeben.txt", True)
    15. For I As Integer = 0 To myArray.Count - 1
    16. If strArr(1).ToString = "" Then
    17. ausgabe.WriteLine("VALUES ('" & strArr(0).ToString & "','')")
    18. Else
    19. ausgabe.WriteLine("VALUES ('" & strArr(0).ToString & "','" & strArr(1).ToString & "')")
    20. End If
    21. Next
    22. ausgabe.Close()
    23. Next
    24. Catch ex As Exception
    25. End Try
    26. End Sub
    27. End Class

    //////////CODE/////////

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „saosinN“ ()

    1) VB-Tags nutzen

    Quellcode

    1. [vb][/vb]

    2) Natürlich hört der Split da auf
    in der 3. Zeite ist keine "(", daher rennt das .Split gegen die Wand!
    Also mal im TryCatch einfügen, dass bei einem Problem die Fehlermeldung kommt und dann alles Debuggen
    @Don_Batisto:
    Nein! Das TryCatch gleich rausnehmen! [VB.NET] TryCatch ist ein heißes Eisen
    Dann sieht man auch, wo der Fehler liegt.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Ja, aber wenn er das schon umbedingt nutzen will, dann soll er in das "Catch ex" auch was reinmachen.

    Manch einer - wie man hier auch wieder sieht - kann nicht richtig Debuggen, wodurch man den Fehler auch erkannt hätte.
    Für diese Leute ist das TryCatch - auch wenn ich es selbst nicht schön finde - der vllt. einzige Ausweg überhaupt
    zu erkennen, warum etwas nicht erfolgreich ist.
    Ich will TryCatch nicht unbedingt nutzen, bin für andere Ideen auch sehr dankbar!

    Ohne TyCatch und mal ganz grob runtergebrochen auf:

    VB.NET-Quellcode

    1. For x = 0 To myArray.Count - 1
    2. str = myArray(x) strArr = str.Split(New Char() {"("c})
    3. MsgBox(strArr(1))
    4. Next



    bekomme ich eine "IndexOutOfRangeExeption" - was ja eigentlich auch logisch ist.
    Leider habe ich keine Idee, wie ich das Problem sonst lösen könnte :/

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „saosinN“ ()

    der vllt. einzige Ausweg überhaupt
    zu erkennen, warum etwas nicht erfolgreich ist.

    Kann ich nicht nachvollziehen.
    Hier ist ein Try-Catch allemal beim IO-Vorgang nötig [Allgemein] [Sammlung] Sinnvolle Verwendungen für Try-Catch
    Hier würde es sich anbieten, einen System.Text.StringBuilder zu verwenden, und anschließend alles mit System.IO.File.WriteAllText(Pfad, SB.ToString, System.Text.Encoding.Default) in einem Ruck auf die Platte zu schreiben.

    andere Ideen

    Sauber programmieren :)

    Du hast das hier:

    Quellcode

    1. das (1)
    2. ist (2)
    3. ein
    4. test (4)


    Ich würde hier folgendes vorschlagen:
    -Du überprüfst mit Zeile.Contains(), ob die Zeile eine öffnende Klammer enthält.
    -Wenn ja:
    --Mit Zeile.IndexOf() holst Du Dir den Index der öffnenden Klammer.
    --Mit Zeile.Remove(Index) bekommst Du das vor der öffnenden Klammer.
    --Mit Zeile.SubString(Index + 1, LängeDerZeile - Index - 2) 'Index + 1, weil ein Zeichen nach Klammer; Das zweite ist die Länge des auszulesenden Textes. - 2 weil eins rechts von der Klammer begonnen werden soll und die Klammer am Ende soll weggelassen werden.
    --

    VB.NET-Quellcode

    1. "VALUES (`" & Erstes & "`, `" & Zweites & "`)"

    -Wenn nein:

    VB.NET-Quellcode

    1. "VALUES (`" & Zeile & "`,``)"


    PS: Ich habe absichtlich ` anstelle von ' verwendet, da sonst hier im Forum alles nach dem ' grün dargestellt wird.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    so.

    scheint ein logischer Ansatz von dir zu sein, allerdings hab ich da noch so meine Probleme mit...

    Statt "zeile." muss ich in meinem fall "str." nutzen, oder?

    VB.NET-Quellcode

    1. str.Contains("(") str.IndexOf(str) str.Remove(index) MsgBox(str)



    bei dem remove-Befehl spuckt er dann: "Fehler 1 "System.Data.Index" ist in diesem Kontext nicht zugreifbar, da es sich um "Friend" handelt." aus. :/

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „saosinN“ ()

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Main()
    3. Dim strArr() As String
    4. Dim t As String
    5. t = "das(1)" & vbCrLf & _
    6. "ist(2)" & vbCrLf & _
    7. "ein" & vbCrLf & _
    8. "test(4)"
    9. t = t.Replace("(", "','").Replace(")", "").Replace(vbLf, "")
    10. Debug.Print(t)
    11. strArr = t.Split(vbCr)
    12. For I As Integer = 0 To 3
    13. If strArr(I).Contains(",") Then
    14. Console.WriteLine("VALUES ('" & strArr(I) & "')")
    15. Else
    16. Console.WriteLine("VALUES ('" & strArr(I) & "',)")
    17. End If
    18. Next
    19. Console.ReadLine()
    20. End Sub
    21. End Module
    @saosinN:
    Schau im ObjectBrowser nach, was String.Remove() und String.SubString() machen. Sie verändern nicht die angegebene Variable!

    Wenn du es dann immer noch nicht verstehst, dann frag nochmal nach. Du sollst ja was dabei lernen, deshalb kaue ich Dir nicht alles vor :)
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Sooooo, ich wollte mich nochmal melden.

    Vielen Dank an alle - @Niko Ortner - mit deiner Methode funktioniert die ganze Geschichte jetzt :)


    Hier der Vollständigkeit halber die Lösung:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Dim t As Integer 'index
    4. Dim s As Integer 'count
    5. Dim m As String 'remove
    6. Dim n As String 'substring
    7. Dim myArray As String()
    8. Dim ausgabe As System.IO.StreamWriter
    9. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles start.Click
    10. myArray = System.IO.File.ReadAllLines("PFADWindowsApplication1\bin\Debug\einlesen.txt", System.Text.Encoding.UTF8)
    11. ausgabe = My.Computer.FileSystem.OpenTextFileWriter("PFAD\WindowsApplication1\bin\Debug\ausgeben.txt", True)
    12. For i = 0 To myArray.Count - 1
    13. If myArray(i).Contains("(") = True Then 'prüfen, ob "(" existiert
    14. t = myArray(i).IndexOf("(") 'index vor "(" speichern
    15. If t <= 0 Then
    16. ElseIf t >= 1 Then
    17. m = myArray(i).Remove(t) 'ab "(" löschen
    18. s = myArray(i).Count 'elemente einer zeile zählen
    19. n = myArray(i).Substring(t + 1, s - t - 2) 'alles vor "(" inc. klammer auf/zu löschen
    20. ausgabe.WriteLine("INSERT INTO AD_Gruppen (GruppenID,Gruppenname)")
    21. ausgabe.WriteLine("VALUES ('" & m & "','" & n & "')")
    22. End If
    23. ElseIf myArray(i).Contains("(") = False Then
    24. ausgabe.WriteLine("INSERT INTO AD_Gruppen (GruppenID,Gruppenname)")
    25. ausgabe.WriteLine("VALUES ('" & myArray(i) & "','')")
    26. End If
    27. Next
    28. ausgabe.Close()
    29. MsgBox("Vorgang abgeschlossen")
    30. End Sub
    31. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles beenden.Click
    32. Me.Close()
    33. End Sub
    34. End Class


    Ist sicherlich nicht perfekt, aber mit dem Gerüst kann ich jetzt weiterarbeiten :)

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „saosinN“ ()

    saosinN schrieb:

    die Lösung:

    Gegenvorschlag ;)

    VB.NET-Quellcode

    1. Dim t As String
    2. t = "das(1)" & vbCrLf & _
    3. "ist (2)" & vbCrLf & _
    4. "ein" & vbCrLf & _
    5. "test (4)"
    6. Dim zeilen = Strings.Split(t, vbCrLf)
    7. For Each zeile In zeilen
    8. Dim Gruppe As String = New String(zeile.TakeWhile(Function(c As Char) Char.IsLetter(c)).ToArray)
    9. Dim ID As String = New String((From p In zeile Where Char.IsNumber(p) Select p).ToArray)
    10. Console.WriteLine("{0} - {1}", Gruppe, ID)
    11. Next