Java conditional regular expression check 24 hours time? ‽

Java conditional regular expression check 24 hours time? ‽ … here is a solution to the problem.

Java conditional regular expression check 24 hours time? ‽

I’m doing the following programming exercise: regex validation of 24 hours time The statement is:

Write a regex to validate a 24 hours time string. See examples to
figure out what you should check for:

Accepted: 01:00 – 1:00

Not accepted:

24:00

You should check for correct length and no spaces.

Excuse me, why does the following regular expression match 24:00

public class RegexValidation {
  public static boolean validateTime(String time) {
    System.out.println("time: "+time);
    return time.matches("(?:^[2])[0123]+:[0-5]+[0-9]|[ 0-9]+:[0-5]+[0-9]");
  }
}

Because I think it’s saying:
“If the string starts with 2, it should continue with [0-3] (one or more): [0-5] one or more and [0-9]. Otherwise it continues with [0-9] one or more: [0-5] one or more and [0-9]. ”

The test is:

import org.junit.Test;
import static org.junit.Assert.*;

public class RegexValidationTest {

@Test
  public void test1() {
    assertTrue(RegexValidation.validateTime("01:00"));
  }

@Test
  public void test2() {
    assertTrue(RegexValidation.validateTime("1:00"));
  }

@Test
  public void test3() {
    assertTrue(RegexValidation.validateTime("00:00"));
  }

@Test
  public void test4() {
    assertFalse(RegexValidation.validateTime("13:1"));
  }

@Test
  public void test5() {
    assertFalse(RegexValidation.validateTime("12:60"));
  }

@Test
  public void test6() {
    assertFalse(RegexValidation.validateTime("24:00"));
  }
}

Also I wrote the following solution and passed the test:

public class RegexValidation {
  public static boolean validateTime/*⌚*/(String time) {
    if(time.matches("[\\d]+:[\\d]{2}")){
      String[] times = time.split(":");
      int hours = Integer.parseInt(times[0]);
      int minutes = Integer.parseInt(times[1]);
      return hours < 24 && minutes < 60;
    }
    return false;
  }
}

I’ve seen it too:

The final question is, why does the regular expression match 24:00 in the first code? ‽

Solution

This is because | exists. After this alternative [0-9]+ matches any number from 1 to 9 and interrupts the desired output.

following regex should do

,

^([01]\d|[ 0-9]|2[0-3]):? ([0-5]\d)$

If : is not optional, remove the ?

^([01]\d|[ 0-9]|2[0-3]):([0-5]\d)$

Also verified on jshell

jshell> var pattern = Pattern.compile("^([01]\\d|[ 0-9]|2[0-3]):? ([0-5]\\d)$");
pattern ==> ^([01]\d|[ 0-9]|2[0-3]):? ([0-5]\d)$

jshell> pattern.matcher("23:01").matches();
$2 ==> true

jshell> pattern.matcher("24:01").matches();
$3 ==> false

jshell> pattern.matcher("00:01").matches();
$4 ==> true

jshell> pattern.matcher("09:01").matches();
$5 ==> true

jshell> pattern.matcher("9:01").matches();
$6 ==> true

jshell> pattern.matcher("12:00").matches();
$7 ==> true

Related Problems and Solutions