Troller
Troller

Reputation: 1138

How to create a time matching Regex pattern

I have been writing a java program. In the program i am taking an input from the user which is a time. I take the input as a string and check if it matches a pattern. The pattern i want is of format : 10:15 AM

This is what i tried but it doesn't seem to work.

public static boolean checkTimePattern(String time) {
    Pattern pattern = Pattern.compile("\\d{1}:\\d{1}^[A]{1}[M]{1}");
   if(pattern.matcher(time).matches()){
       return true;
   }else{
       return false;
   }
}

Thank you.

Upvotes: 2

Views: 259

Answers (5)

cafebabe1991
cafebabe1991

Reputation: 5176

There are couple of things that were not correctly understood by you while you were using the regex

1.) ^ is a reserved character by the regex, so you have to escape it when using it. Although it has been used here incorrectly, but still if you want to work, escape it using backslash ().

So the expression (Although still INCORRECT but should have been like this)

         \\d{1}:\\d{1}\^[A]{1}[M]{1}                        <- Watch carefully \^

2.) @GhostCat advice is correct, use SimpleDateFormat here.

3.) If you still want to go ahead with the regex , it should look this to match the pattern.

        \\d{2}:\\d{2}\\s+(AM|PM)

Understand the regex part by part now

\\d{2} -> This says two digits exactly

: -> This says a colon after the two digits

\\d{2} -> This says two digits exactly after colon

\\s+ -> This says match any no. of space characters after XX:XX , you may skip it as it is just to make your regex more robust.

(AM|PM) -> This is a capture group, and says that match either AM OR(|) PM and nothing else.

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626747

Your regex only allows 1 hour digit and 1 minute digit, and requires a start of string to appear before A. That makes little sense.

The best way to validate time (or date), use SimpleDateFormat:

String s = "10:15 AM";
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a");
sdf.setLenient(false);
try {
   Date dt2 = sdf.parse(s);
   System.out.println(dt2);
}
catch (Exception exc) {
    System.out.println(s + " IS NOT VALID TIME");
}

If you are bound to use regex, use

//Regex
String pat = "[0-1]?[0-2]:[0-5][0-9]\\s*[Aa][Mm]";
if (s.matches(pat)){
    System.out.println("Regex matches the string!");
}

(Where [0-1]?[0-2] matches 0 to 12 hours, [0-5][0-9] matches 0 to 59 minutes, \\s* matches zero or more whitespaces, [Aa][Mm] matches Am, AM, aM or am. If a leading 0 is required, remove the ? from after [0-1].)

See the Java demo

Upvotes: 2

Raman Sahasi
Raman Sahasi

Reputation: 31841

  1. Why are you using ^? There's no use of that. An Exponent is used assert position at start of the string but I don't see any use of this to match Time.

  2. The digits are either 1 or 2 digits. The \d{1} indicates that only one digit would be there. You should instead use \d{1,2} which indicates either one or max two digits.

  3. There's not need to follow [A] by {1}. It itself means that only one character and that's A. If you want to add support for PM as well then you can use [AP] followed by simply [M] or simply M.

You can use this RegEx

\d{1,2}:\d{1,2}\s[AP][M]

escaped format would be:

\\d{1,2}:\\d{1,2}\\s[AP][M]

DEMO

Upvotes: 1

GhostCat
GhostCat

Reputation: 140427

Simply stop right there. Java already has a mechanism to parse strings that contain date / time values.

It is fine to study regular expression, but do not use them for something that already exists in the framework. Your solution will always be deficient compared to what SimpleDateFormat is already doing for you!

Upvotes: 5

Ray Man
Ray Man

Reputation: 75

you should test your regex first, try http://rubular.com/

\d{2}[:]\d{2}\s*[A][M] //should work, this is the general regex

dont put ^, in the middle that means the start of a string, ($ means end check the guidelines at the bottom of the screen at rubular.com

Upvotes: -1

Related Questions