Consider the following:
>>> import re
>>> a = "first:second"
>>> re.findall("[^:]*", a)
['first', '', 'second', '']
>>> re.sub("[^:]*", r"(\g<0>)", a)
'(first):(second)'
re.sub()'s behavior makes more sense initially, but I can also understand re.findall()'s behavior. After all, you can match an empty string between first and : that consists only of non-colon characters (exactly zero of them), but why isn't re.sub() behaving the same way?
Shouldn't the result of the last command be (first)():(second)()?