You are misunderstanding what [...]
does. They are character classes; if 1 character in that class matches, the text matches:
>>> import re
>>> re.search(r'[32]', '3')
<_sre.SRE_Match object; span=(0, 1), match="3">
>>> re.search(r'[32]', '2')
<_sre.SRE_Match object; span=(0, 1), match="2">
Don’t use a character class when you only want to match literal text.
The following would only match your specific 2-digit patterns:
r = re.compile('^([048]$)|(-?[0-9]*(12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)')
This works as expected:
>>> r = re.compile('^([048]$)|(-?[0-9]*(12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)')
>>> r.search("32")
<_sre.SRE_Match object; span=(0, 2), match="32">
>>> r.search("33")
>>> r.search("33") is None
True
You are not matching numbers ending in 00
however (like 100, 200, etc.), which are also divisible by 4.
Note that the expression can be reduced further; the digits 0, 4 and 8 only follow even numbers while the digits 2 and 6 always follow odd numbers:
r = re.compile('^-?(?:[048]|[0-9]*(?:[02468][048]|[13579][26]))$')
I moved the -
sign check out to apply to all numbers.
2
solved Number divided by 4 by python regex