I have date
in my .txt
file which comes like either of the below:
mmddyyyy
OR
mm/dd/yyyy
Below is the regex which works fine for mm/dd/yyyy
.
^02\/(?:[01]\d|2\d)\/(?:19|20)(?:0[048]|[13579][26]|[2468][048])|(?:0[13578]|10|12)\/(?:[0-2]\d|3[01])\/(?:19|20)\d{2}|(?:0[469]|11)\/(?:[0-2]\d|30)\/(?:19|20)\d{2}|02\/(?:[0-1]\d|2[0-8])\/(?:19|20)\d{2}$
However, unable to build the regex for mmddyyyy
. I just want to understand is there any generic regex that would work for both cases?
CodePudding user response:
If you want to match all those variations with either 2 forward slashes or only digits, you can use a positive lookahead to assert either only digits or 2 forward slashes surrounded by digits.
Then in the pattern itself you can make matching the /
optional.
Note that you don't have to escape the \/
^(?=\d (?:/\d /\d )?$)(?:02/?(?:[01]\d|2\d)/?(?:19|20)(?:0[048]|[13579][26]|[2468][048])|(?:0[13578]|10|12)/?(?:[0-2]\d|3[01])/?(?:19|20)\d{2}|(?:0[469]|11)/?(?:[0-2]\d|30)/?(?:19|20)\d{2}|02/?(?:[0-1]\d|2[0-8])\?(?:19|20)\d{2})$
Another option is to write an alternation |
matching the same pattern without the /
in it.
CodePudding user response:
Why use regex for this? Seems like a case of "Now you have two problems"
It would be more effective (and easier to understand) to use a DateTimeFormatter
(assuming you are on the JVM and not using scala-js)
import java.time.format.DateTimeFormatter
import java.time.LocalDate
val mdyNoSlash = DateTimeFormatter.ofPattern("MMddyyyy")
val mdyWithSlash = DateTimeFormatter.ofPattern("MM/dd/yyyy")
def attemptParse(rawDate: String) = {
Try { LocalDate.parse(rawDate, mdyNoSlash) }.orElse {
Try { LocalDate.parse(rawDate, mdyWithSlash) }
}.get
}
Testing in REPL
scala> attemptParse("12252022")
val res13: java.time.LocalDate = 2022-12-25
scala> attemptParse("12/25/2022")
val res14: java.time.LocalDate = 2022-12-25
scala> attemptParse("25/12/2022")
java.time.format.DateTimeParseException: Text '25/12/2022' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 25