0

I'm supposed to check whether a string matches a certain pattern. The pattern is as follows

dd.mm.yyyy HH:mm;score;duration
  • notice the space between yyy and HH
  • score being an int value
  • duration being a double value

How to construct a regex pattern concerning the above problem? What have I missed in my code or have done wrong?

I'm mainly confused about the special characters like semicolon, colon, space bar and when to use \ or \\

public HighscoreEntry(String data) {

    String pattern= "^(3[01]|[12][0-9]|0?[1-9])\\.\\(1[0-2]|0?[1-9])\\.\\(20[0-9]{2})\\s\\(2[0-4]|[01][0-9])\\:\\(5[0-9]|[0-4][0-9]\\;\\d+\\;\\d*\\.\\d+$"; 

    if(data.matches(pattern)){
...
Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
Bitte
  • 3
  • 1
  • Is using regex a requirement? Because usually trying to use regex to check if a date is valid is not the best way to go. (eG: How would you tell your regex that the 29. february is only valid in some specific years?) – OH GOD SPIDERS Jun 26 '19 at 13:33
  • Possible duplicate of [Regex date format validation on Java](https://stackoverflow.com/questions/2149680/regex-date-format-validation-on-java) – Dushyant Tankariya Jun 26 '19 at 13:34
  • To verify your Regex you can use [LINK](https://regex101.com/). – Dushyant Tankariya Jun 26 '19 at 13:35
  • If I understand you correctly you are not matching a date only, this is a date plus 2 other values in a string? Maybe you could add some examples to your question. – Joakim Danielson Jun 26 '19 at 13:36
  • This can be one ```(\d{1,2}).(\d{1,2}).(\d{4})\s(\d{1,2}):(\d{1,2});(\d*);(\d*\.\d*)``` regex that gets you all those elements. do note that this will not validate the actual date, example if you get a two digit number 48 in dd, the regex will still match. – Yogesh_D Jun 26 '19 at 13:37

2 Answers2

0

A more relaxed expression

^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2};\d+;\d.\d*$

And one that takes into consideration the possible date and time values

^[0-3][0-9]\.[0-1][0-9]\.\d{4} [0-2][0-9]:[0-5][0-9];\d+;\d*.\d*$

To use them in a Java string each \ needs to be escaped by a \, so \ -> \\

I haven't tested the patterns so some typos might exist

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
0

Since the question is: Finding the best regex pattern and not What is the best regex pattern, I am going to answer this. The technique I use is more or less a divide and conquer approach.

First, find the delimiters. Then you can build your pattern like this:

String pattern = field1() + ";" + field2() + "|" + field3(); 

Then your fields may have data types. Please note, that not every (string representation of a) domain is regular! So check this first. In your example, you want something like this:

String pattern = intPattern(2) + "\\." + intPattern(2) + "\\." + intPattern(4)
               + " " + intPattern(2) + ":" + intPattern(2)
               + ";" + intPattern() + ";" + doublePattern();

Where intPattern(n) gives a pattern for an unsigned integer with exactly n digits, intPattern() gives a pattern for arbitrarily many digits.

Advantages:

  1. You can test the patterns individually.
  2. You don't end up with a ultra-long regex which looks like a mess

But your example suggests, that you want more than just verifying the pattern. What you want is semantics. You want to check, that dd.MM.yyyy is actually a valid date. This is impossible, because the language of correct dates is (in general) not regular. If you only consider a finite subset of dates (e.g. from year 1990 to 2400) you can do this (finite languages are always regular), but it will be a mess.

UniversE
  • 2,419
  • 17
  • 24