2

I have input string in next format : 12:00am|1:20PM|9:30Pm

I need to have in output array of hours like : [12:00am, 1:20PM, 9:30Pm]

But before I shoudl match it with regex.

I have some regex to match AmPm hours and I tried to add | to match full string \b((1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))([|])?. This regex matches string 12:00am|1:20PM|9:30Pm but also matches string 12:00am|1:20PM}9:30Pm which isn't correct.

Where is my mistake in my regex and how can I return expected array.

Thanks

demo
  • 6,038
  • 19
  • 75
  • 149
  • What a [similar question](https://stackoverflow.com/questions/44175731/regular-expression-for-5-comma-separated-email-id). Check [this comment](https://stackoverflow.com/questions/44175731/regular-expression-for-5-comma-separated-email-id#comment75366499_44175731). It is advisable to split with `"|"` and check if all the items match `^(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])$`. – Wiktor Stribiżew May 25 '17 at 09:17
  • @WiktorStribiżew, thanks, I will check it – demo May 25 '17 at 09:18
  • 1
    See https://jsfiddle.net/4xmzw5p3/1/. So, split first, then validate. Does it meet your requirements? – Wiktor Stribiżew May 25 '17 at 09:25

1 Answers1

1

The \b((1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))([|])? does not require | as [|]? matches 1 or 0 occurrences of this char. This regex matches 12:00am|1:20PM}9:30Pm as it finds 12:00am and calls it a day (i.e. returns a valid match).

You need to split the string with | and validate each item against /^(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])$/ pattern.

var s = "12:00am|1:20PM|9:30Pm";
var re = /^(1[0-2]|0?[1-9]):[0-5][0-9]([AaPp][Mm])$/;
var items = s.split("|");
if (items.filter(function(x) { return re.test(x); }).length === items.length) {
   console.log("VALID => ", items);
} else {
 console.log("INVALID!");
}

Note you may use a regex to pre-validate the string, but it is just more cumbersome:

var s = "12:00am|1:20PM|9:30Pm";
var re_block = "(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])";
var re = new RegExp("^" + re_block + "(?:\\|" + re_block + ")*$");
var isValid = re.test(s);
console.log(isValid ? s.split("|") : "Invalid!");

The regex will look like /^(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])(?:\|(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))*$/ and it will validate a string that starts with the time substring, and then has 0 or more occurrences of time substrings up to the string end. See the pattern demo.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563