TAGS :Viewed: 4 - Published at: a few seconds ago

[ Why does this provided regular expression return true? ]

I would like to know why following regular expression returns true:

reg = re.compile (r'[0-9]%')
reg.search ("50%")

[0-9] would match any single digit, in this case 5. But then 0 doesn't match %, so it should return false, but it returns true.

My code might have syntax errors, but you get the gist of it.

Answer 1

reg.search() matches the pattern anywhere in the string (so it matches the 0%). If you want the entire string to match, try this:


^ - matches the start of the string

$ - matches the end of the string

Answer 2

This regex would match on the 0% portion of 50%.

Answer 3

If you are searching for single-digit percentages inside a longer string, you could use a negative lookbehind:

In [171]: print(re.search('(?<!\d)\d%',"Foo is 5% complete"))
<_sre.SRE_Match object at 0xab302f8>

In [172]: print(re.search('(?<!\d)\d%',"Foo is 50% complete"))

In [173]: print(re.search('(?<!\d)\d%',"5% complete"))
<_sre.SRE_Match object at 0xab301a8>

In [174]: print(re.search('(?<!\d)\d%',"50% complete"))

Answer 4

As gfdunn2 mentioned, it does a 'rolling-match' of the entire string. There are a couple things you can do to control it a bit better though.

The braces {} below can control how many characters you get, so it will give you much tighter matching.

>>> import re  

#exactly 1 digit and %
>>> test = re.compile(r'[0-9]{1}%')  
>>> print test.search("50%").group(0)  

#exactly 2 digits and %
>>> test = re.compile(r'[0-9]{2}%')  
>>> print test.search("50%").group(0)  

#one or more digits  
>>> test = re.compile(r'[0-9]+%')  
>>> print test.search("50%").group(0)  

#in the event you want to include floating point percentages  
>>> test = re.compile(r'[0-9.]+%')  
>>> print test.search("50.4%").group(0)  

>>> print test.search("50.34%").group(0)