String bei Leerzeichen unterteilen, aber in Anführungszeichen nicht.

  • C#
  • .NET (FX) 4.5–4.8

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

    String bei Leerzeichen unterteilen, aber in Anführungszeichen nicht.

    Guten Tag,

    Ich zerbreche mir gerade den Kopf wie ich einen String in dem Format Wort wort wort "noch mehr wort" ach ja wort nach Leerzeichen unterteilen kann, dabei allerdings bei Leerzeichen in Anführungszeichen keine Unterteilung zu machen.

    Als ineefiziente Lösung habe ich mir bereits überlegt einfach Split("\"") zu machen und dann solche mit " wieder zusammenzulegen.

    Ich gehe davon aus das es bestimmt eine bessere / effizientere Lösung, z.b. mit RegEx gibt, allerdings hält sich mein wissen diesbezüglich in grenzen und auch meine Suche konnte mir leider nicht so ganz nahe legen wie RegEx funktionieren.


    Ich wäre dankbar wenn mich jemand in die richtige Richtung lenken könnte.


    Grüße,
    Luca
    こんにちわ
    Achte beim stellen von Fragen auf eine genaue Fragestellung, mir passiert das selbst häufig, andere können dir dann nicht so gut helfen.
    @LuaX Dann splitte zuerst an den Apostrophrn, ohne die leeren Einträge zu eliminieren. Wisse dann, welche Parts (nominell jeder zweite) apostrophierte Parts sind und bearbeite die anderen.
    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!
    Ah gut das wäre auch eine möglichkeit, aber wie könnte ich hier umsetzen das "Escapierte Anfühungszeichen" \" ignoriert werden?


    Grüße
    こんにちわ
    Achte beim stellen von Fragen auf eine genaue Fragestellung, mir passiert das selbst häufig, andere können dir dann nicht so gut helfen.
    @LuaX: Schrieb RfG doch. Hier ein Beispiel (auch wenn meine C#-Kenntnisse ... ausbaufähig sind):

    C#-Quellcode

    1. string[] parts = textBox1.Text.Split('\"');
    2. char[] charSeparators = new char[] {' '};
    3. for (int i = 0; i < parts.Count(); ++i)
    4. if (i != 1)
    5. {
    6. foreach (string part in parts[i].Split(charSeparators, StringSplitOptions.RemoveEmptyEntries))
    7. MessageBox.Show(part);
    8. }
    9. else
    10. MessageBox.Show(parts[i]);

    Aber: Das funktioniert nur, wenn der Aufbau wirklich so ist, wie Du beispielhaft gezeigt hast. Sinnvoller wäre eine Auflistung Deinerseits, welche Fälle es alles geben kann, sonst wird das hier ziemliches Spekulatiusbacken.

    Oh, EdR war deutlich schneller. Da hab ich mir wohl zuviel Zeit gelassen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    So etwas ähnliches hatte ich auch schon, musste es also nur noch kurz anpassen und ins C# übersetzen.
    Am Schluss hast den Teil in Anführungszeichen und den anderen Teil Separat in der Variabel
    Kannst also res[0] nochmals Splitten, wenn du willst.

    Freundliche Grüsse

    exc-jdbi

    Vb.Net

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Module SplitProbe
    4. Public Sub Main()
    5. Dim ic = Convert.ToInt32(""""c)
    6. Dim str = String.Format("Wort wort wort {0}An Führungs Zeichen{0} ach ja wort", Convert.ToChar(ic))
    7. Dim res = GetSpecialSplit(str, Convert.ToChar(ic))
    8. Stop
    9. End Sub
    10. Private Function GetSpecialSplit(s As String, c As Char) As String()()
    11. If CheckCount(s, c) Then
    12. Dim substr = GetSubString(s, c)
    13. Dim newstr = Elimination(s, substr).Split({" "c}, StringSplitOptions.RemoveEmptyEntries)
    14. Return {substr, newstr}
    15. End If
    16. Return Nothing
    17. End Function
    18. Private Function GetSubString(s As String, c As Char) As String()
    19. If String.IsNullOrEmpty(s) Then Return Nothing
    20. If CheckCount(s, c) Then
    21. Dim idx = Enumerable.Range(0, s.Count).Where(Function(x) s(x) = c)
    22. Dim res = New String(idx.Count \ 2 - 1) {}
    23. For i = 0I To idx.Count - 1 Step 2
    24. res(i \ 2) = s.Substring(idx(i) + 1, idx(i + 1) - idx(i) - 1)
    25. Next
    26. Return res
    27. End If
    28. Return Nothing
    29. End Function
    30. Private Function Elimination(s1 As String, s2() As String) As String
    31. If String.IsNullOrEmpty(s1) OrElse s2 Is Nothing OrElse
    32. s2.Length < 1 Then Return Nothing
    33. Dim idx1, idx2 As Int32
    34. Dim res = New List(Of String)
    35. idx1 = 0 : idx2 = 0
    36. For Each s As String In s2
    37. idx2 = s1.IndexOf(s, idx1)
    38. If idx2 >= 0 Then res.Add(s1.Substring(idx1, idx2 - idx1 - 1).Trim)
    39. idx1 = idx2 + s.Length + 1
    40. Next
    41. If idx1 < s1.Length Then
    42. res.Add(s1.Substring(idx1, s1.Length - idx1).Trim)
    43. End If
    44. Return String.Join(" ", res.ToArray)
    45. End Function
    46. Private Function CheckCount(s As String, c As Char) As Boolean
    47. If s.Count(Function(cc) cc = c) Mod 2 = 0 Then Return True
    48. Return False
    49. End Function
    50. End Module

    C#

    C#-Quellcode

    1. using System;
    2. using System.Linq;
    3. using System.Diagnostics;
    4. using System.Collections.Generic;
    5. using Microsoft.VisualBasic.CompilerServices;
    6. public static class SplitProbe
    7. {
    8. public static void Main()
    9. {
    10. int ic = Convert.ToInt32("\2");
    11. string str = string.Format("Wort wort wort {0}An Führungs Zeichen{0} ach ja wort", Convert.ToChar(ic));
    12. var res = GetSpecialSplit(str, Convert.ToChar(ic));
    13. Debugger.Break();
    14. }
    15. private static string[][] GetSpecialSplit(string s, char c)
    16. {
    17. if (CheckCount(s, c))
    18. {
    19. var substr = GetSubString(s, c);
    20. var newstr = Elimination(s, substr).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    21. return new[] { substr, newstr };
    22. }
    23. return null;
    24. }
    25. private static string[] GetSubString(string s, char c)
    26. {
    27. if (string.IsNullOrEmpty(s))
    28. return null;
    29. if (CheckCount(s, c))
    30. {
    31. var idx = Enumerable.Range(0, s.Count).Where(x => s(x) == c);
    32. var res = new string[idx.Count / 2];
    33. for (int i = 0, i< idx.Count ; i += 2)
    34. res[i/2] = s.Substring(idx[i] + 1, idx[i + 1] - idx[i] - 1);
    35. return res;
    36. }
    37. return null;
    38. }
    39. private static string Elimination(string s1, string[] s2)
    40. {
    41. if (string.IsNullOrEmpty(s1) || s2 == null || s2.Length < 1)
    42. return null;
    43. int idx1, idx2;
    44. var res = new List<string>();
    45. idx1 = 0; idx2 = 0;
    46. foreach (string s in s2)
    47. {
    48. idx2 = s1.IndexOf(s, idx1);
    49. if (idx2 >= 0)
    50. res.Add(s1.Substring(idx1, idx2 - idx1 - 1).Trim());
    51. idx1 = idx2 + s.Length + 1;
    52. }
    53. if (idx1 < s1.Length) res.Add(s1.Substring(idx1, s1.Length - idx1).Trim);
    54. return string.Join(" ", res.ToArray());
    55. }
    56. private static bool CheckCount(string s, char c)
    57. {
    58. if (s.Count(cc => cc==c) % 2 == 0)
    59. return true;
    60. return false;
    61. }
    62. }

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „exc-jdbi“ ()

    Regex for splitting a string using space when not surrounded by single or double quotes

    C#-Quellcode

    1. using System;
    2. using System.Text.RegularExpressions;
    3. public class Example
    4. {
    5. public static void Main()
    6. {
    7. string pattern = @"[^\s""']+|""([^""]*)""|'([^']*)'";
    8. string input = @"Wort, wort wort, ""noch, mehr wort"" ach, ja wort";
    9. foreach (Match m in Regex.Matches(input, pattern))
    10. {
    11. Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
    12. }
    13. }
    14. }

    LuaX schrieb:

    "Escapierte Anfühungszeichen"
    sind Quellcode, kein "normaler" Text.
    Poste eine vollständige und belastbare Aufgabenstellung, wie bereits @ErfinderDesRades forderte.
    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!