2015-07-24 3 views
6

Ich versuche, in einem String ein - zwischen allen ungeraden Zahlen zu platzieren. Wenn also ein String als Hel776o übergeben wird, sollte er Hel7-76o ausgeben. Bindestriche sollten nur zwischen zwei aufeinanderfolgenden ungeraden Zahlen stehen.Java Stelle eines „-“ zwischen ungeraden Zahlen in einer Zeichenfolge mit Regex

Ich versuche, dies über String.replaceAll in einer Zeile() zu tun

Ich habe die folgende Zeile:

return str.replaceAll(".*([13579])([13579]).*","$1-$2"); 

Wenn jede ungerade Zahl ist, durch eine ungerade Zahl Platz folgte ein - zwischen Sie. Aber es ersetzt alles bis auf das letzte Spiel destruktiv.

Wenn ich zB "999477" übergebe, wird 7-7 anstelle von 9-9-947-7 ausgegeben. Werden mehr Gruppierungen benötigt, also ersetze ich nicht alles außer den Spielen?

Ich habe das schon mit einem traditionellen Schleife durch die einzelne Zeichen in Zeichenfolge aber wollte es in einem Einzeiler mit Regex tun ersetzen.

Edit: Ich würde sagen, ich meine return str.replaceAll(".*([13579])([13579]).*","$0-$1"); und nicht $1 und $2

+1

Nehmen Sie die '. *' da dies alles vor den letzten zwei ungeraden Ziffern fallen lässt. –

Antwort

9

entfernen .* aus Ihrem regex raubend alle Zeichen in einem Spiel zu verhindern.

Auch wenn Sie zuvor einen Teil wiederverwenden möchten, passen Sie es nicht verbrauchen kann. Zum Beispiel, wenn die Zeichenfolge wird 135 und Sie werden passen 13 Sie nicht in der Lage sein werden, mit 5 dass abgestimmt 3 wieder in der nächsten Partie wieder zu verwenden.
Zur Lösung dieses Problems look-around Mechanismen verwenden, die zero-length sind, was bedeutet, werden sie Teil nicht verbrauchen sie übereinstimmen.

So Ort zu beschreiben, die hinter (?<=[13579]),

  • ungeradee Zahl, nachdem es (?=[13579]) verwenden Vorgriff

    • ungeradee Zahl vor dem Gebrauch Look.

    So kann Ihr Code aussehen

    return str.replaceAll("(?<=[13579])(?=[13579])","-"); 
    

    Sie können auch nur eine von zwei ungeraden Zahlen regex verbrauchen lassen andere wiederverwendet werden zu lassen:

    return str.replaceAll("[13579](?=[13579])","$0-"); 
    
    return str.replaceAll("(?<=[13579])[13579]","-$0"); 
    
  • +0

    Diese Erklärung hilft. Ich habe nicht erkannt, dass es einen Mechanismus zum Umschauen gibt, der den Charakter, den ich gerade verarbeitet habe, nicht konsumiert. Ich habe auch vergessen, meinen Code zu aktualisieren, um $ 0 und $ 1 anstelle von $ 1 und $ 2 versehentlich zu verwenden! – Help123

    +0

    In Ihrem Fall schien '$ 1' und' $ 2' korrekt zu sein. Ich benutze '$ 0', die ganze Übereinstimmung darstellen, weil ich keine explizite Erfassungsgruppe hinzugefügt habe. – Pshemo

    +0

    I modifizierte es wie: return str.replaceAll ("? ([13579]) (= [13579])", "$ 1"); Ich versuche, die Nuancen von Regex zu lernen, und für jetzt finde ich es einfacher, eine explizite Gruppenaufnahme zu machen – Help123

    Verwandte Themen