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;
 

Flown

Administrator
Mitarbeiter
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);
 

SuperSheriff

Mitglied
Dankeschön, ja geht wohl sehr einfach, wenn man weiß wie :D
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.
 

Flown

Administrator
Mitarbeiter
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();
}
 

SuperSheriff

Mitglied
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
 

SuperSheriff

Mitglied
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
 
K

kneitzel

Gast
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 \\.
 

SuperSheriff

Mitglied
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
 
K

kneitzel

Gast
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.
 

SuperSheriff

Mitglied
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.
 

Joose

Top Contributor
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.
 
X

Xyz1

Gast
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("(.) ....
 
X

Xyz1

Gast
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
 

Jardcore

Top Contributor
Manchmal weiß ich nicht ob ich das ernst nehmen soll :p 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.
 
X

Xyz1

Gast
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
 

Ähnliche Java Themen

Neue Themen


Oben