Splitzeichen in Array lassen

  • Allgemein

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Splitzeichen in Array lassen

    Hi,

    Ich möchte einen Satz splitten z.B anhand der Satzzeichen, aber das Splitzeichen soll im Array drin bleiben.

    Bsp:

    VB.NET-Quellcode

    1. Dim str ="Ich gehe davon aus, dass es einfach ist. Das bla"
    2. Dim splitter = {","c, "."c}
    3. Dim Arr() = str.Split(splitter)


    So sollte das aussehen:

    Quellcode

    1. Arr(0) = "Ich gehe davon aus"
    2. Arr(1) = ","
    3. Arr(2) = "dass es einfach ist"
    4. Arr(3) = "."
    5. Arr(4) = "Das bla"


    Wie kann ich das bewerkstelligen?

    8-) faxe1008 8-)
    Ich denke, IndexOf() ist performanter als RegEx.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi
    oder schreib' dir schnell eine Funktion dafür:

    VB.NET-Quellcode

    1. Shared Iterator Function Split(input As String, ParamArray delimiters() As String) As IEnumerable(Of String)
    2. Dim lind As Integer = 0
    3. Dim cind As Integer = 0
    4. While cind < input.Length
    5. For j As Integer = 0 To delimiters.Length - 1
    6. Dim del As String = delimiters(j)
    7. Dim ismatch As Boolean = True
    8. For k As Integer = 0 To del.Length - 1
    9. If input(cind + k) <> del(k) Then
    10. ismatch = False
    11. Exit For
    12. End If
    13. Next
    14. If ismatch Then
    15. Yield input.Substring(lind, cind - lind)
    16. Yield del
    17. lind = cind + del.Length
    18. cind = lind
    19. Continue While
    20. End If
    21. Next
    22. cind += 1
    23. End While
    24. Yield input.Substring(lind, cind - lind)
    25. End Function


    Gruß
    ~blaze~
    Damit bleibt das Trennzeichen allerdings halt auch nicht im Array oder anders verfügbar, soweit ich das sehe. IndexOfAny gibt's halt nicht für String-Arrays, sonst hätte ich das verwendet. Man kann den Code von mir btw. auch noch optimieren.
    Was hast du denn dagegen, es über so einen einfachen Algorithmus zu lösen?

    Gruß
    ~blaze~
    Ich hätte mir auch wahrscheinlich was selber gebastelt wie du @~blaze~:, indem ich den String einfach mit Substring durchgehe und schaue ob einer der Splitter vorhanden ist wenn ja kommt der String vom letzten Splitter bis zum jetzigen in das Array und danach der Splitter selbst. Da ich allerdings 3 oder 4 Zeichen suche, lohnt es den Aufwand eigentlich fast nicht wenn ich es so biegen kann.
    Agitas Lösung ist brauchbar, denn in den Strings kommt kein | vor, welches das Spliten behindern würde. :thumbsup:

    Aber trotzdem dem Lernwille halber: Was hat das Iterator in der Function oben zu bedeuten? Und was bewirkt Yield?

    8-) faxe1008 8-)
    so wie ErfinderDesRades es schon vorgeschlagen hat mit regex:

    VB.NET-Quellcode

    1. Dim str = "Ich gehe davon aus, dass es einfach ist. Das bla und so lala. blabla, sowie so . oder doch nicht? ... "
    2. Dim splitter = {","c, "."c}
    3. Dim Arr() = Text.RegularExpressions.Regex.Split(str, "([\.,])")
    4. For i As Integer = 0 To Arr.Length - 1
    5. Console.WriteLine(Arr(i))
    6. Next
    7. Console.ReadKey()


    ich sag ma meine variante hat sich erledigt ;)
    denk mal nach, wenn du zb den string "..." hast ... der wird gereplaced zu "|.||.||.|" und das wiederum wird gesplittet in ["", ".", "", ".", "", ".", ""]
    es entstehen also lücken =/

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Agita“ ()

    Lies dich einfach mal hier hinein, ist bisschen viel zu erklären:
    msdn.microsoft.com/de-de/library/dscyy5s0(v=vs.120).aspx
    Was passt dir an meinem nicht? Sicher, die Effizienz ist nicht die beste (und du kannst den Code auch so modifizieren, dass er dir den Index des Trennzeichens zurückgibt, oder so, einfach den Rückgabetyp abändern und statt Yield delimiter(k) Yield New KeyValuePair(Of Integer, String)(k, input.Substring(... reinschreiben).

    Gruß
    ~blaze~
    @Artentus: Werde ich morgen inner Freistunde anschauen :thumbup:

    ~blaze~ schrieb:

    Was passt dir an meinem nicht?


    Alles passt, ich hatte nur schon Agitas Lösung probiert und es hat funktioniert.

    Habe auch an was gebastelt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function NewSplit(ByVal sen As String, ByVal splitter As Char()) As List(Of String)
    2. Dim str = sen
    3. Dim final_list As New List(Of String)
    4. Dim last_found As Integer = 0
    5. For u = 0 To str.Length - 1
    6. For Each Chr As Char In splitter
    7. If str.Substring(u, 1) = Chr Then
    8. final_list.Add(str.Substring(last_found, u - last_found))
    9. final_list.Add(str.Substring(u, 1))
    10. last_found = u + 1
    11. End If
    12. Next
    13. Next
    14. If last_found < str.Length Then
    15. final_list.Add(str.Substring(last_found, str.Length - last_found))
    16. End If
    17. Return final_list
    18. End Function

    8-) faxe1008 8-)
    @Agita: Das ist aktezptabel, da kein Splitter mehrmals hintereinander kommt.

    @~blaze~: Hier ;) (Habs ausversehen in VB2008 geschrieben wo Strict auf Off stand :rolleyes: )
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function NewSplit(ByVal sen As String, ByVal splitter As Char()) As List(Of String)
    2. Dim final_list As New List(Of String)
    3. Dim last_found As Integer = 0
    4. For u = 0 To sen.Length - 1
    5. For Each Chr As Char In splitter
    6. If Char.Parse(sen(u)) = Chr Then
    7. final_list.Add(sen.Substring(last_found, u - last_found))
    8. final_list.Add(sen(u))
    9. last_found = u + 1
    10. End If
    11. Next
    12. Next
    13. If last_found < sen.Length Then
    14. final_list.Add(sen.Substring(last_found, sen.Length - last_found))
    15. End If
    16. Return final_list
    17. End Function



    Aber eine Anschlussfrage hätte ich hierbei:

    ~blaze~ schrieb:

    durch sen(x)


    Warum kann ich bei einem String über den Index einen Char auslesen, obwohl so oft hier im Forum behauptet wurde, dass Strings keine Char Arrays sind?

    8-) faxe1008 8-)
    Ein String ist auch kein Char-Array, aber trotzdem besteht ein String ja aus einzelnen Chars und implementiert daher z.B. auch IEnumerable<char>.

    Es ist übrigens auch alles Definitionssache.
    Wenn man "Char-Aaray" als char[] definiert, dann ist ein String halt keins, weil es sind ja offensichtlich zwei unterschiedliche Klassen.
    Man könnte aber auch definieren, ein Char-Array ist ein Bereich im Speicher, in dem mehrere Unicode-Zeichen hintereinander liegen. Das trifft dann auf beide Klassen zu.
    Das sind halt so OOP-Fallen, weil selbst wenn ich den Code von einer Klasse in die andere 1zu1 reinkopiere, sinds immer noch zwei verschiedene Klassen, auch wenn der Speicher exakt gleich aussieht.

    ErfinderDesRades schrieb:

    Dim arr = str.Replace("."c, "|.|").Replace(","c, "|,|").Split("|"c)

    Geht auch noch kürzer. Die String.Replace-Funktion akzeptiert ein Char-Array als ersten Parameter ;)