2017-07-25 6 views
2

Ich versuche, Teile einer Zeichenfolge zu ersetzen, die enthält, was Datumsangaben sein sollten, die aber möglicherweise in einem unzulässigen Format sind. Insbesondere haben alle Daten das Format "MM/TT/JJJJ" und müssen das Format "JJJJ-MM-TT" haben. Eine Einschränkung ist, dass die ursprünglichen Daten nicht genau im Format MM/TT/JJJJ sein dürfen; einige sind wie "5/6/2015". Wenn beispielsweiseScala regex find/replace mit zusätzlicher Formatierung

val x = "where date >= '05/06/2017'" 

dann

x.replaceAll("'([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})'", "'$3-$1-$2'") 

führt den gewünschten Ersatz (returns "2017.05.06"), aber für

val y = "where date >= '5/6/2017'" 

dies den gewünschten Ersatz nicht zurück (gibt "2017-5-6" zurück - für mich eine ungültige Darstellung). Mit dem Joda Zeit Wrapper nscala-time, habe ich versucht, die Daten zu erfassen und dann Neuformatierung:

import com.github.nscala_time.time.Imports._ 
import org.joda.time.DateTime 

val f = DateTimeFormat.forPattern("yyyy-MM-dd") 
y.replaceAll("'([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})'", 
    "'"+f.print(DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime("$1"))+"'") 

Aber das scheitert mit einem java.lang.IllegalArgumentException: Invalid format: "$1". Ich habe auch versucht, die f Interpolator und Padding mit 0s, aber es scheint auch nicht so.

Können Sie keine zusätzliche Verarbeitung für die erfassten Gruppen ($1 usw.) innerhalb der replaceAll durchführen? Wenn nicht, wie kann ich sonst das gewünschte Ergebnis erzielen?

Antwort

2

Die $1 like-Backreferences können nur in String-Ersetzungsmustern verwendet werden. In Ihrem Code ist "$1" keine Rückreferenz mehr.

Sie verwenden ein „Rückruf“ mit replaceAllIn, um tatsächlich das Spiel Objekt zu erhalten und Zugriff auf seine Gruppen weiter, sie zu manipulieren:

val pattern = "'([0-9]{1,2}/[0-9]{1,2}/[0-9]{4})'".r 
y = pattern replaceAllIn (y, m => "'"+f.print(DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime(m.group(1)))+"'")