C# Leerzeichen außer zwischen " entfernen?

lordfritte

Lieutenant
Registriert
Juli 2006
Beiträge
955
Hallo ich habe eine Zeichenkette die wie folgt aussieht: string s = "12, 56.33 , \"Hallo Welt\"";
Ich möchte nun alle Leerzeichen außer zwischen \" entfernen, also am ende soll das ganze so aussehen: "12,56.33,\"Hallo Welt\""
 
Du kannst den String in ein Array splitten, ausgehend von dem Anführungszeichen. Jeder String mit ungeradem (eigentlich jeder 2. String, da hier aber mit 0 angefangen wird zu zählen) Index wird dann von der Replace-Aktion ausgeschlossen, die du bei allen anderen Strings im Array mit einer "int i=0; i<Array.Length; i+2"-Schleife durchführst.

Hoffe ich konnte dir helfen.;)
 
Zuletzt bearbeitet:
edit, achso das soll innerhlab des programmes geschehen.. ja dann ist alles klar :>
 
@Cyba_Mephisto: Das funktioniert nicht, wenn der String mit einem " anfängt.
 
Cyba_Mephisto schrieb:
Du kannst den String in ein Array splitten, ausgehend von dem Anführungszeichen. Jeder String mit ungeradem (eigentlich jeder 2. String, da hier aber mit 0 angefangen wird zu zählen) Index wird dann von der Replace-Aktion ausgeschlossen, die du bei allen anderen Strings im Array mit einer "int i=0; i<Array.Length; i+2"-Schleife durchführst.

Hoffe ich konnte dir helfen.;)

Danke, diese Idee hatte ich auch schon, aber wie sieht es mit der Ausführungszeit aus?
Aber diese Methode ist doch sicher schneller als Regex oder?

Darii schrieb:
@Cyba_Mephisto: Das funktioniert nicht, wenn der String mit einem " anfängt.

Warum nicht? Wenn er mit " beginnt ist doch " an Position 0, das kann man doch Prüfen
 
Also eigentlich löst man so ein Problem über reguläre Ausdrücke. Außerdem könntest du die Leerzeichen auch einfach manuell entfernen, ist zwar auch net ideal, aber da weißt du wenigstens, was das Programm exakt macht...

So wäre die Idee:
so lange der Zähler nicht am String-Ende ist aktuelles Zeichen anschauen...
ist es ein Anführungszeichen so wird eine Boolean-Variable, ob wir uns in einem (ich nenn es einfach mal Zitat auch wenn das falsch ist) Zitat befinden...
ist es ein Leerzeichen, so wird abhängig davon, ob die Boolean-Variable wahr oder falsch ist entweder das Zeichen entfernt und der Zähler um 1 verringert
am Ende der Schleife noch Zähler um 1 erhöhen

elegant ist das aber auch nicht und wie man es am elegantesten mit RegEx macht kann ich leider auch nicht sagen :-)

der Code sähe etwa so aus
Code:
bool quotation = false;
int i = 0;
while (i < s.length) {
  if (s[i] == '"') quotation = !quotation;
  if ((s[i] == ' ') && (!quotation)) {
    s.RemoveAt(i);           // keine Ahnung ob die Methode so heißt ^^
    i--;
  }
  i++;
}

Edit: Die Frage ist: Ist die Ausführungsgeschwindigkeit denn relevant? Wieviele Strings müssen denn so abgeklappert werden?
 
Zuletzt bearbeitet:
Ja ich habs ungefähr genau so:

PHP:
string ReplaceSpaceCharacter(string sExpression)
    {
      bool bReplace = true;

      for (int i = 0; i < sExpression.Length; i++)
      {
        if (sExpression[i] == '"' && bReplace)
          bReplace = false;
        if (sExpression[i] == '"' && !bReplace)
          bReplace = true;
        if (sExpression[i] == ' ' && bReplace)
        {
          sExpression = sExpression.Remove(i, 1);
          i--;
        }
      }

      return sExpression;
    }

EDIT: Was ich komisch finde: Hier
if (sExpression == '"' && bReplace)
bReplace = false;
muss ich i wieder eins höher setzen sonst geht es nicht.
 
Zuletzt bearbeitet:
naja die beiden ersten IFs kannst du zusammenfassen...
ich weiß nicht mal ob das wirklcih so viel langsamer ist... wobei es gibt noch einen Weg... aber keine Ahnung ob der wirklich eine kürzere Laufzeit hat...

Code:
string ReplaceSpaceCharacter(string sExpression)
    {
      bool bReplace = true;
      int j = 0;
      for (int i = 0; i < sExpression.Length; i++)
      {
        if (sExpression[i] == '"') bReplace = !bReplace;
        if (sExpression[i] != ' ' || !bReplace)
        {
          j++;
        }
        sExpression[j] = sExpression[i];
      }
      sExpression = sExpression.Remove(j, sExpression.Length - j); // muss noch geprüft werden ob das so stimmt
      return sExpression;
    }

edit: Ah schade, man kann gar nicht schreibend auf sExpression[j] zugreifen, also geht es in C# so nicht...

Edit:
Dein Code kann gar nicht funktionieren weil so bald das erste IF wahr wurde, ist sicher auch das zweite IF wahr...

So muss es sein (oder halt noch nen "else" rein bei dir oben):
Code:
string ReplaceSpaceCharacter(string sExpression)
        {
            bool bReplace = true;

            for (int i = 0; i < sExpression.Length; i++)
            {
                if (sExpression[i] == '"') bReplace = !bReplace;
                if (sExpression[i] == ' ' && bReplace)
                {
                    sExpression = sExpression.Remove(i, 1);
                    i--;
                }
            }

            return sExpression;
        }

Edit: So nen Fehler hättest du übrigens ganz leicht mit Breakpoints/Einzelschrittanweisungen gefunden...
 
Zuletzt bearbeitet:
Ah klar stimmt, wenn ich oben auf false setze is das 2. if automatisch true
 
Logisch, so geht´s natürlich auch, ich fand´s nur mit dem Array "kürzer". Das Array kann ja nachher eh freigegeben werden.
 
Noch eine Frage am Rande, in welcher Richtung wird if aufgelöst, von rechts nach links oder von links nach rechts?

Also wird das hier: wert1 && wert2 || wert3,

wird das in der Reihenfolge aufgelöst:
wert1 && wert2
ergebnis || wert3

oder so:
wert2 || wert3
ergebnis && wert1
 
Schwer zu sagen, gibt Sprachen in denen es in die eine und Sprachen in denen es halt in die andere Richtung geht.
Code, der auf solchen Eigenschaften beruht, sollte vermieden werden, da sich hier sehr schnell Fehler einschleichen können und das auch nicht immer ganz offensichtlich ist.

In dem Fall hier allerdings würde eine Klammer reichen :-)

Wenn du allerdings z.B. einen Funktionsaufruf hast hinten beim wert3, der eben true oder false zurückliefert, aber evtl noch mehr macht, dann kann es sein dass wenn wert1 und wert2 bereits true sind das wert3 gar nicht mehr ausgeführt wird...

@Cyba_Mephisto: Ist halt die Frage ob's auch in Sachen Laufzeit kürzer ist... ehrlich gesagt hab ich keine Ahnung. Der Punkt ist halt dass der String bei der Schleife genau einmal durchgegangen wird, bei dem Split usw mehrmals - andererseits sind das wiederum meistens optimierte Methoden usw... müsste man einfach mal testen...
 
string s = "12, 56.33 , \"Hallo Welt\"";

Dann kommt beim Split mit " heraus:
s[0]=12, 56.33 , \
s[1]=Hallo Welt\
s[2]=Bleibt leer

Die ersten "" sind für die Stringverpackung im Compiler notwendig. ;)
 
Dein string s beginnt aber nicht mit einem Gänsefüßchen... Wenn du schon was probierst, dann bitte richtig... außerdem glaube ich kaum dass s[0] und s[1] einen Backslash enthalten, denn im string s kommt gar kein Backslash vor...
Also bitte wenn du schon so was hier postest, dann teste es auch wirklich... zudem ist s[0] ein Char und '1'.
 
Zuletzt bearbeitet:
Zurück
Oben