Fails to match when using backreference

50 Views Asked by At

I want to match
9:00 AM to 5:00 PM

This is my regex, I am trying to use backreference match the time at the end, it is not working
(\d(?::\d{2})?\s\wM)\sto\s\1

If simply replacing the backreference makes it match, why is the backreference failing ?
(\d(?::\d{2})?\s\wM)\sto\s(\d(?::\d{2})?\s\wM)

My questions are,
How can I use a backreference to match the time at both ends ?
Why is what I did not working ?

regexr.com/7dbki

2

There are 2 best solutions below

3
Simon On BEST ANSWER

I think there is a misconception of what \1 does. It does not re-use the pattern, as if it was a placeholder for the expression you put in parenthesis. Rather, it matches whatever was captured in the first capturing group.

In your case, your pattern would match e.g. this:

  • 9:00 AM to 9:00 AM

See here: https://regex101.com/r/M8u6eO/1

If your regex engine supports it, you may use "?1".

(\d:\d{2}?\s\wM)\sto\s(?1)

See here: https://regex101.com/r/OytMlt/1

This will indeed re-use the pattern instead of the match.

1
Ciprian Galbeaza On

The backreference is not working because it is capturing the whole time string, including the "AM" or "PM" part. Since the two time strings have different "AM" or "PM" parts, the backreference does not match.

To fix the regex and use a backreference, you can capture only the time part (hour and minute) and use separate backreferences for both the hour and minute parts. Here's a working regex:

(\d(?::(\d{2}))?\s\wM)\sto\s\1

Regex breakdown:

  • (\d(?::(\d{2}))?\s\wM): Capture the whole time string, including the "AM" or "PM" part.
  • \d: Capture the hour part.
  • (?::(\d{2}))?: Optionally capture the minute part, including the colon.
  • \s\wM: Match the "AM" or "PM" part.
  • \sto\s: Match " to " in between the two time strings.
  • \1: Backreference to the first captured group (the whole time string).

Note that with this regex, you're not validating if the first part is "AM" and the second part is "PM". If you want to ensure this, you can modify the regex like this:

(\d(?::(\d{2}))?\sAM)\sto\s(\d(?::\d{2})?\sPM)

This regex ensures that the first part ends with "AM" and the second part ends with "PM".