简体   繁体   中英

Regular expression to validate time

I am using the Regular Expression "(?:[0-1]?[0-9]|[2][1-4]):[0-5]?[0-9]\\s?(?:AM|am|PM|pm)?" to validate time.

var Regexp = new RegExp("(?:[0-1]?[0-9]|[2][1-4]):[0-5]?[0-9]\s?(?:AM|am|PM|pm)?");
if (Regexp.test(starttime)) {
    var match = Regexp.exec(starttime);
    if (match) {
        s = match[0];
    }
}

My input is "7:00 AM" . But my match[0] returns only "7.00" . This does not return AM or PM . There also seems to be only one group. How do I get AM/PM with the group?

The main problem is that you're using a string to define the regular expression, and using \\s within that string. \\ in strings is an escape character, so the regex doesn't see the \\s , it just sees s (because "\\s" === "s" , the escape doesn't actually do anything). You'd need \\\\s instead.

But far better to use literal syntax:

var rex = /(?:[0-1]?[0-9]|[2][1-4]):[0-5]?[0-9]\s?(?:AM|am|PM|pm)?/;

(I also changed the name, Regexp is just too close to RegExp .)

Live Example:

 var starttime = "7:00 AM"; var rex = /(?:[0-1]?[0-9]|[2][1-4]):[0-5]?[0-9]\\s?(?:AM|am|PM|pm)?/; if (rex.test(starttime)) { var match = rex.exec(starttime); if (match) { snippet.log(match[0]); } } 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

(?:) defines a non-capturing group. Remove the ?: if you want capturing groups.


As there is some confusion this is a more complete answer:

If you want s to contain "7:00 AM" you can either use the literal syntax // or escape the \\s with another slash ( \\\\s ). Note that match[0] is not a group but the full match.

If you want first group - the time and second one - am/pm - this slight modification will do :

 ((?:[0-1]?[0-9]|[2][1-4]):[0-5]?[0-9])\\s?(AM|am|PM|pm)? 

You have an escape sequence issue, where \\s becomes s in your regex.

However, even after you use the preferred literal syntax to fix that issue, you still have to consider a couple of edge cases. 24:00 should not be a time, and 20:00 should be, so change your [1-4] to [0-3] . Secondly, 23:00 AM makes no sense nor does 13:00 PM . To fix this, you should split your regex into two pieces so that you match either a 12 hour time, or a 24 hour time. Thirdly, the time 7:0 PM also matches, because you have a ? after your first minutes digit. There should always be two minutes digits.

As always with regex, make test cases! This will help you see where your regex is going wrong (or not going wrong).

Working regex: (Thanks to TJ Crowder for the awesome snippet tool)

 var tests = ["20:00", "24:00", "13:00 PM", "7:0 AM", "7:00 AM"]; var regex12hrTime = /((0?[0-9])|(1[0-2])):[0-5][0-9]\\s?(AM|am|PM|pm)/; var regex24hrTime = /([0-1][0-9]|2[0-3]):[0-5][0-9]/; for (var idx=0; idx<tests.length; idx++) { var test = tests[idx]; if (regex12hrTime.test(test)) { snippet.log(test + " matches with " + regex12hrTime.exec(test)[0]); } else if (regex24hrTime.test(test)) { snippet.log(test + " matches with " + regex24hrTime.exec(test)[0]); } else { snippet.log(test + " does not match"); } } 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM