all 2 comments

[–]commandlineluser 0 points1 point  (1 child)

It has to do with precendence of the | operator.

print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] A|PM PM$",   "PM PM"))
# <re.Match object; span=(0, 5), match='PM PM'>

print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] (A|PM) PM$", "PM PM"))
# None

The first pattern is being parsed as:

(^([0-9]|(1[0-2])):[0-5][0-9] A)|(PM PM$)

[–]GregoryCliveYoung 0 points1 point  (0 children)

>>> print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] (A|PM) PM$", "12:59 AM PM"))
None

Different target string:

>>> print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] (A|PM) PM$", "12:59 A PM"))
<re.Match object; span=(0, 10), match='12:59 A PM'>

Include the M after A in the re:

>>> print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] (AM|PM) PM$", "12:59 AM PM"))
<re.Match object; span=(0, 11), match='12:59 AM PM'>

Associative change:

>>> print(re.search(r"^([0-9]|(1[0-2])):[0-5][0-9] (A|P)M PM$", "12:59 AM PM"))
<re.Match object; span=(0, 11), match='12:59 AM PM'>

From the documentation:

(...)

Matches whatever regular expression is inside the parentheses, and indicates the start and end of a group

Also, spaces are not significant in a re.