2016-11-19 6 views
5

Ich habe eine Zeichenfolge wie s = "abc.def..ghi". Ich möchte das einzelne "." mit zwei .s. s.replace(".", "..") ergibt jedoch "abc..def .... ghi". Wie kann ich das richtige Verhalten erhalten? Die Ausgabe, die ich suche, ist s = "abc..def..ghi".Ersetzen von Zeichen in einer Zeichenfolge, Java

Antwort

6

den Punkt nur ersetzen, wenn es durch zwei Zeichen

umgeben ist
String foo = s.replaceAll("(\\w)\\.(\\w)", "$1..$2"); 

Oder wie @Thilo kommentierte nur, wenn sie von zwei nicht Punkte

umgeben ist
String foo = s.replaceAll("([^.])\\.([^.])", "$1..$2"); 

Und den einzelnen Punkt durch zwei Punkte ersetzen, auch wenn der Punkt am Anfang/Ende von t ist er Zeichenfolge, verwenden Sie eine negative Vorschau und Lookbehind: (Beispiel String: .abc.def..ghi. wird ..abc..def..ghi.. werden)

String foo = s.replaceAll("(?<!\\.)\\.(?!\\.)", ".."); 
+0

Können Sie eine gute "Erste Schritte mit Regex" Ressource empfehlen? – Adam

+2

Ich tinke http://www.regular-expressions.info/ ist nicht so schlimm, obwohl es nicht sehr schön aussieht. Aber du wirst dort sehr viel finden. Der Lookahead/Behind wird hier erklärt: http://www.regular-expressions.info/lookaround.html @Adam – baao

-6
s.replace("...",".."); 
s.replace("....",".."); 

Abhängig von Eingabemöglichkeiten ..

+0

Ich meine, er muss diese nach dem ersten Anruf an Stelle verwenden. Außerdem muss er dem Eingabestrom einer solchen Zeichenfolge eine gewisse Kontrolle auferlegen, sonst kann ihm kein Parser auf der Welt helfen. –

+0

Bitte werfen Sie einen Blick auf die Antwort von baao und überlegen Sie, ob Sie diese Antwort löschen möchten. –

3

Wenn Sie nicht wissen, wie es zu tun regex dann StringTokenizer verwenden, um die Zeichenfolge zu spalten und wieder verketten mit ...

Code:

public static void main(String[] args) { 
    String s = "abc.def..ghi"; 
    StringTokenizer s2 = new StringTokenizer(s, "."); 
    StringBuilder sb = new StringBuilder(); 


    while(s2.hasMoreTokens()) 
    { 
     sb.append(s2.nextToken().toString()); 
     sb.append(".."); 
    } 
    sb.replace(sb.length()-2, sb.length(), ""); // Just delete an extra .. at the end 

    System.out.println(sb.toString()); 

} 

Ich weiß, dass der Code groß ist im Vergleich zu einer Linie regex, aber ich habe es für den Fall, wenn Sie irgendwelche Probleme mit regex haben. Wenn Sie denken, dass es langsamer als die angenommene Antwort ist, habe ich eine Start- und Endzeit mit System.currentTimeMillis() gemacht und ich habe meine schneller. Ich weiß nicht, ob es Ausnahmen zu diesem Test gibt.

Wie auch immer, ich hoffe es hilft.

+0

Ich glaube nicht, dass dies funktioniert, wenn Sie drei aufeinander folgende Punkte haben (obwohl, um fair zu sein, das erwartete Verhalten unterspezifiziert ist Ich nehme an, du möchtest sie als drei Punkte behalten und nicht in zwei Punkte verwandeln. – Thilo

+0

@Thilo Ich habe Punkte mit Start, Ende und mit mehreren Punkten (> 3) dazwischen versucht. Es funktionierte. – SkrewEverything

+0

@Thilo es ist 'a..b' – SkrewEverything

2

Verwenden Blick Arounds:

str = str.replaceAll("(?<!\\.)\\.(?!\\.)", "..")(

Die Regex liest als „ein Punkt, nicht mit einem Punkt vorangestellt, und nicht durch einen Punkt gefolgt“. Dies behandelt die Kantenfälle eines Punktes am Anfang/Ende und/oder umgeben von buchstäblich jedem anderen Zeichen.

Da Look-arounds keine Eingaben konsumieren, müssen Sie sich im Ersatzbegriff nicht mit Backreferenzen anfreunden.

Verwandte Themen