1

I'm pretty sure I'm missing something very elementary here as I'm normally ok with Python & Regex. I'm looking to see if the string supplied contains at least one number, and this is the command line I'm going through, but always getting false...

>>> import re
>>> test_string = "123567890"
>>> pat = re.compile("[0-9]")
>>> pat.search(test_string) == True
False

Before posting this I've tried a few other permutations and not getting very far, what am I doing wrong?

Mike
  • 1,814
  • 4
  • 22
  • 36

4 Answers4

4

pat.search doesn't return a Boolean value but a MatchObject so your comparison will fail:

In [9]: p = pat.search(test_string)

In [10]: p
Out[10]: <_sre.SRE_Match at 0x3cfa608>

In [11]: type(p)
Out[11]: _sre.SRE_Match

See re.search docs:

re.search(pattern, string, flags=0)

Scan through string looking for a location where the regular expression pattern produces a match, and return a corresponding MatchObject instance. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.

Levon
  • 138,105
  • 33
  • 200
  • 191
  • Thank you, I misinterpreted the doc slightly where it says "Match Objects always have a boolean value of True, so that you can test whether e.g. match() resulted in a match with a simple if statement"! – Mike Jun 30 '12 at 23:30
0

The problem is that the re.search() method does not actually return a bool, it returns a specialized regexp. match object. bool(pat.search(test_string)) should return True, viz.:

>>> import re
>>> test_string = "123567890"
>>> pat = re.compile("[0-9]")
>>> bool(pat.search(test_string))
True

The normal way to check for a successful match is simply to use the if construct, i.e.:

>>> if pat.search(test_string): True
... 
True

You can use this abbreviated form of truth-testing for any object that implements one of either the __nonzero__ or __len__ special methods.

Greg E.
  • 2,722
  • 1
  • 16
  • 22
0

re.search returns a MatchObject when it finds a match, not a boolean. It DOES return None when it doesn't match, so this would do what you're trying to do:

pat.search(test_string)!=None
Sean Johnson
  • 5,567
  • 2
  • 17
  • 22
  • 2
    When comparing with `None` you should use `is not None` (or `is None` for the inverse) – ThiefMaster Jun 30 '12 at 23:20
  • 1
    `is None`/`is not None` is preferred over the use of comparison operators. Because `is` can be implemented as a simple pointer comparison, it performs no method look-up and is slightly faster, it's semantically cleaner, and it guards against the (admittedly unlikely) scenario of the `__eq__` special method being overwritten (q.v., http://stackoverflow.com/questions/11166748/identity-versus-equality-for-none-in-python/). – Greg E. Jun 30 '12 at 23:22
0

Here's how you should use match objects. I normally need more than a True/False from a match object, so I always save it away.

>>> m = pat.search(test_string)
>>> bool(m) == True
True
>>> if m:
        print "true"
true
robert
  • 33,242
  • 8
  • 53
  • 74