Java - How do i find out that a string is in the correct format using pattern matching

105 Views Asked by At

My string value;

09:00-10:00,12:00-14:30,16:00-18:00 (this string repeats time intervals n times like this)

and I want to find out that a string is in the correct format using pattern matching;

Pattern.matches("<Pattern Here>", stringValue);

is it possible?

I tried;

Pattern.matches("^[0-9:0-9-0-9:0-9,]+$", value);

But doesn't work properly

2

There are 2 best solutions below

10
On BEST ANSWER

You can use the following pattern for any given range of 2 times in the form of 24h clock:

private static final String HOURLY_TIME_PATTERN = "([01][0-9]|2[0-3]):([0-5][0-9])";
private static final String TIME_RANGER_PATTERN = HOURLY_TIME_PATTERN + "-" + HOURLY_TIME_PATTERN;
private static final String PATTERN = "^" + TIME_RANGER_PATTERN + "(," + TIME_RANGER_PATTERN + "?)*$";
private static final Pattern pattern = Pattern.compile(PATTERN);

public static void main(String[] args) {
    String input = "09:00-10:00,12:00-14:30,16:00-18:00";
    if (pattern.matcher(input).matches()) {
        System.out.println("We have a match!");
    }
}

Explanation:

  • HOURLY_TIME_PATTERN is the pattern required for a single hour in a 24h format (e.g. 16:25)
  • TIME_RANGER_PATTERN is the pattern to find a single time range (e.g. 16:25-22:50)
  • PATTERN - is the pattern that ensure that we have at least 1 time range, and any other time range must be lead by a comma (we can have zero or more of them)
6
On

You can check if the string matches the regex, ^(?:(?:\d{2}:\d{2}\-\d{2}:\d{2})(?:,(?!$))?)*$. Note that you do not need to put starts-with (i.e. ^) and ends-with (i.e. $) when using String#matches.

If the string passes this validation, split the string on , and - and then use java.time API to validate the individual time strings.

Demo:

import java.time.LocalTime;
import java.time.format.DateTimeParseException;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(hasCorrectFormat("09:00-10:00,12:00-14:30,16:00-18:00")); // true
        System.out.println(hasCorrectFormat("09:00-10:00,12:00-1:30,16:00-18:00")); // false -> 1:30 is not in desired
                                                                                    // format
        System.out.println(hasCorrectFormat("09:00-10:00")); // true
        System.out.println(hasCorrectFormat("09:00 10:00")); // false
        System.out.println(hasCorrectFormat("09:00-10:00,09:00 10:00")); // false
        System.out.println(hasCorrectFormat("09:00-10:00-12:00-14:30,16:00-18:00")); // false
        System.out.println(hasCorrectFormat("09:00-10:00,12:00-14:30,16:00-18:00,")); // false
    }

    static boolean hasCorrectFormat(String strTimeRanges) {
        if (!strTimeRanges.matches("(?:(?:\\d{2}:\\d{2}\\-\\d{2}:\\d{2})(?:,(?!$))?)*"))
            return false;
        String[] times = strTimeRanges.split("[-,]");
        for (String time : times) {
            try {
                LocalTime.parse(time);
            } catch (DateTimeParseException e) {
                return false;
            }
        }
        return true;
    }
}

Output:

true
false
true
false
false
false
false

Regex demo

Learn more about the modern Date-Time API from Trail: Date Time.


The valuable comment from Ole V.V. has prompted me to extend my original answer to show how one can use java.time API to compare the times in individual time ranges. I hope this gives enough hints for learners to extend the solution further based on the complexity of the requirements.

import java.time.LocalTime;
import java.time.format.DateTimeParseException;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00,12:00-14:30,16:00-18:00")); // true
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00,12:00-1:30,16:00-18:00")); // false -> 1:30
        System.out.println(hasCorrectFormatAndRanges("10:00-09:00,12:00-14:30,16:00-18:00")); // false -> 10:00-09:00
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00")); // true
        System.out.println(hasCorrectFormatAndRanges("09:00 10:00")); // false
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00,09:00 10:00")); // false
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00-12:00-14:30,16:00-18:00")); // false
        System.out.println(hasCorrectFormatAndRanges("09:00-10:00,12:00-14:30,16:00-18:00,")); // false
    }

    static boolean hasCorrectFormatAndRanges(String strTimeRanges) {
        if (!strTimeRanges.matches("(?:(?:\\d{2}:\\d{2}\\-\\d{2}:\\d{2})(?:,(?!$))?)*"))
            return false;
        String[] timeRanges = strTimeRanges.split(",");
        for (String timeRange : timeRanges) {
            String[] times = timeRange.split("-");
            try {
                if (LocalTime.parse(times[1]).isBefore(LocalTime.parse(times[0])))
                    return false;
            } catch (DateTimeParseException e) {
                return false;
            }
        }
        return true;
    }
}

Output:

true
false
false
true
false
false
false
false