Stringmanipulation

SuperSheriff

Mitglied
Hallo zusammen,

Ich bin neu hier und arbeite auch erst seit wenigen Wochen mit Java, deshalb verzeiht mir meine wohl doofe frage.

Und zwar geht es darum wie man aus einem String ein Zeichen heruaslöscht, welches mehrfach hintereinander vorkommt.

Sprich ("12//347/57///") --> zu ("12/347/57/")

Ich komm einfach nicht drauf, ich hab mir überlegt den veränderten String in ein neues char Array zu speichern, aber ich finde den passenden Algorithmus einfach nicht.

Ich hab mich irgendwie total verrannt.

Hier der Code, vielen Dank im Voraus 🙂

Java:
//Hilfsvariablen
            int pnameLaenge = pname.length();
            int pruefer = 0;
            int zaehler = 0;
            int zaehler2 = 0;
            char []name2 = {};
           
            //Normalisierung der Strings
            pname.replace('/', java.io.File.separatorChar);
           
            //Doppelte / Mehrfrache seperatorChars werden rausgefiltert
            for(int i = 0; i < pnameLaenge;){
               
                if(pname.charAt(i) == java.io.File.separatorChar &&
                    pname.charAt(i + zaehler + 1) == java.io.File.separatorChar){
                    zaehler++;
                }else{
                    name2[zaehler2] = pname.charAt(i+zaehler+1);
                    i = i + zaehler + 1;
                    zaehler = 0;
                    zaehler2++;
                }
            }name2[0] = pname.charAt(0) + "" + name2;
 
Mit Regex geht das sehr gut:
Java:
String s = "12//347/57///";
String clean = s.replaceAll("/{2,}", "/");
System.out.println(s);
System.out.println(clean);
 
Dankeschön, ja geht wohl sehr einfach, wenn man weiß wie 😀
Ich hab schon ein bisschen c programmiert, deshalb versuch ich oft die Methoden selbst zu schreiben.
In diesem Fall ist es blos nicht ganz ohne.
 
Geht auch ganz ohne Regex:
Java:
public static String clean(String s) {
  StringBuilder builder = new StringBuilder(s.length());
  for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (i == 0 || c != '/' || s.charAt(i - 1) != c) {
      builder.append(c);
    }
  }
  return builder.toString();
}
 
Vielen Dank schon mal 😉

ich hätte noch ne frage und zwar warum funktioniert das nicht (Code unten)?

Java:
String s = "/////////";
      
        s.replace('/',java.io.File.separatorChar);


Auf Windows müsste doch nun "\\\\\\\\\" herauskommen
 
Wie funktioniert
Code:
String clean = s.replaceAll("/{2,}", "/");

mit meinem java.io.File.charSeparator.

ich möchte immer meinen CharSeparator einzeln haben auch wenn bei der angabe 2 oder mehr hintereinander sind darf er immer nur einzeln stehen
 
Code:
String clean = s.replaceAll("/{2,}", File.separatorChar == '\\' ? "\\\\" : "" + File.separatorChar);

Sowas sollte funktionieren.

Edit: Code ersetzt - dachte eigentlich, dass er da beim Ersetzen nicht versucht, zu escapen, aber da habe ich mich geirrt. Daher die neue Version mit dem abfangen des \ und ersetzen durch \\.
 
habs jzt so gemacht:

Code:
String clean = pname.replace('\\','/');
            pname = clean;
           
            clean = pname.replaceAll("/{2,}", "/");
            pname = clean;

bin mir jzt aber nicht mehr sicher ober linux und windows kompatibel ist mhm
 
Ja, sorry. Ich hatte erwartet, dass String.replaceAll beim Ersatz-String nicht versucht, Escape Zeichen auszuwerten. Aber ich hatte es vorsichthalber selbst getestet und meinen Beitrag noch einmal editiert. Diese Lösung funktioniert - wenn separator ein \ ist, dann wird er durch \\ ersetzt, wobei zur Anzeige von \\ ein "\\\\" benötigt wird.
 
Danke 🙂

so müsste es auf linux und win gehen oder?

Java:
String clean = pname.replace('\\','/');
            pname = clean;
          
            clean = pname.replaceAll("/{2,}", "/");
            pname = clean;
          
            clean = pname.replace('/',java.io.File.separatorChar );

weil weder und win noch in linux dafr der fileseparator doppelt vorkommen, so passt dann glaub ich.
 
Hinweis: Deine Variable clean ist nicht (zwingend) notwendig.
Code:
pname = pname.replace('\\','/');
pname = pname.replaceAll("/{2,}", "/");
Du kannst den neuen String direkt wieder Variable zuweisen.
 
Du könntest das mit einer Methode machen:
Java:
        String alt = "///12//347/57///";
        String neu = "" + alt.charAt(0);
        for (int i = 1; i < alt.length(); i++) {
            if (alt.charAt(i - 1) != alt.charAt(i)) {
                neu += alt.charAt(i);
            }
        }
        System.out.println("alt = " + alt);
        System.out.println("neu = " + neu);

Das ist dasselbe wie ein komplizierter Regex, beginnt mit: System.out.println(alt.replaceAll("(.) ....
 
Ein regulärer Ausdruck ist einheitlich und für jeden, der sich kurz in reguläre Ausdrücke einliest, verständlich. Wenn man nun eigene Methoden für jede String Behandlung bastelt, passiert es spätestens beim Arbeiten im Team, dass unnötiger workload für die Erklärung von Code ensteht.

Wegen der Komplexität ist also ein regulärer Ausdruck im Team einfacher zu verstehen als eine einfache Schleife?

Na dann schreib mal deinen Regulären Ausdruck auf, wenn er so einfach wäre.
Tipp: Backreferences ist ein guter Ansatzpunkt und auch auf Stack Overflow hab ich auf die Schnelle dazu nichts gefunden, deshalb schreibe ich ihn hier auch nicht.

Vergiss nicht, das ich hier der Wissende bin - und nicht du. Ich hab auch kein Probl. damit, ein aktives Mitglied zu kritisieren.

Bis dann
 
Manchmal weiß ich nicht ob ich das ernst nehmen soll 😛 Ein aktives Mitglied hat übrigens keinen großartigen Stellenwert, wer viel schreibt, kann auch viel Mist schreiben 🙂

Zum Thema:
Reguläre Ausdrücke haben sich etabliert und können in jeder Programmiersprache gleich eingesetzt werden. Wenn es um die Validierung von Strings geht, kommt kein Weg dran vorbei, diese auch zu benutzten.
Na dann schreib mal deinen Regulären Ausdruck auf, wenn er so einfach wäre.
Siehe oben, da steht der schon.
 
Siehe oben, da steht der schon.

Von einem Mod hingwurstelt, ohne die Aufgabenstellung zu beachten.

Ein Regex, der der Aufgabenstellung entspräche, wäre:
Java:
String alt = "///12//347/57///";
System.out.println(alt.replaceAll("(.)\\1{1,}", "$1"));

(1 Zeile) Der ist natürlich ganz einfach. Was kriege ich jetzt dafür, für den Regex, den du nicht kanntest und der im Team einfacherer wäre? Auf welches Konto kannst du die 1000 $ überweisen?

Bis dann
 

Zurück
Oben