What's wrong with my regular expression?
I'm expecting a string NOT to match a regular expression, but it is!
>>> re.compile('^P|([LA]E?)$').match('PE').group()
'P'
This seems like a bug, because I see no way for the $ to match. On the other hand, it seems unlikely that Python's re lib would not be able to handle this simple case. Am I missing something here?
btw, Python prints this out when I start it:
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for开发者_高级运维 more information.
^P|([LA]E?)$
becomes
^P
|
([LA]E?)$
You wrote "P or ([LA]E?)". "P" matches.
If you meant for the anchors to apply to both cases, then perhaps you meant this:
^(?:P|([LA]E?))$
Two other points worth mentioning: ^
is redundant when you use re.match()
, and if you want to match the end of the string, use r"\Z"
, not "$".
Why $ is evil: Suppose we want to check that the whole of some string s
matches some pattern foo
. We don't want to call it a match if there is anything after the pattern. Let's see what happens if there is a newline after the pattern.
>>> import re
>>> s = 'foo\n'
>>> re.match('foo$', s)
<_sre.SRE_Match object at 0x00BAFE90> # match -- FAIL!
>>> re.match('foo\Z', s) # no match -- OK
>>>
Here are excerpts from the docs:
Docs for $
: Matches the end of the string or just before the newline at the end of the string ... this is using the default modes, and is nothing to do with MULTILINE mode.
Docs for \Z
: Matches only at the end of the string. Nothing to do with modes, and not spooked by newlines.
It will match either ^P
or ([LA]E)$
. Did you mean ^(?:P|([LA]E?))$
instead?
It prints the same output on Mac OS X and on Linux(Debian testing). I would be surprised to see a bug behave the same on three major platforms. Besides, 'PE' has 'P' in the beginning, so I don't see a problem in it matching the regex. Similarly, 'AE' matches the regex too. On both Debian and on Mac OS X.
精彩评论