1

In the match

'meeting room 3 @ 5 am - 6 pm bob'
.match(/(@|at)?\s*?(\d+)\s*?(am|pm|AM|PM)?\s*?-\s*?(\d+)\s*?(am|pm|AM|PM)?/)

Why does the last pm not match?

The result is "["@ 5 am - 6","@","5","am","6",null]"

I expect that null to be pm

Thanks

1
  • 2
    Remove ? from all \s*?. Commented Feb 22, 2018 at 22:44

1 Answer 1

2

Make all the \s*? greedy (especially the last one which is the culprit):

/(@|at)?\s*(\d+)\s*(am|pm|AM|PM)?\s*-\s*(\d+)\s*(am|pm|AM|PM)?/
                                               ^

See the regex demo

The point is that (\d+)\s*?(am|pm|AM|PM)? matches and captures 1 or more digits with (\d+), then the regex engine tries to match (am|pm|AM|PM)? pattern, not \s*?, because \s*? is a lazily quantified atom, and is thus skipped at first. The (am|pm|AM|PM)? pattern can match an empty string, and it does. It matches the empty string right after the digits, and the regex engine calls it a day returning a valid match.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I did not realize the regex engine skips lazy matches at first. Makes sense, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.