5

I would like to left pad zeros to the number in a string. For example, the string

hello120_c

padded to 5 digits should become

hello00120_c

I would like to use re.sub to make the replacement. Here is my code:

>>> re.sub('(\d+)', r'\1'.zfill(5), 'hello120_c')

which returns

>>> 'hello000120_c'

which has 6 digits rather than 5. Checking '120'.zfill(5) alone gives '00120'. Also, re.findall appears to confirm the regular expression is matching the full '120'.

What is causing re.sub to act differently?

2
  • 2
    You are zfilling before the replacement. Your code is equivalent to re.sub('(\d+)', r'000\1', 'hello120_c'). You have to use a callback, as in Wiktor's answer, to defer the filling to when you actually have the match. Commented Jan 21, 2016 at 10:22
  • @tobias_k thanks for the explanation :). Commented Jan 21, 2016 at 10:42

1 Answer 1

3

You cannot use the backreference directly. Use a lamda:

re.sub(r'\d+', lambda x: x.group(0).zfill(5), 'hello120_c')
# => hello00120_c

Also, note that you do not need a capturing group since you can access the matched value via .group(0). Also, note the r'...' (raw string literal) used to declare the regex.

See IDEONE demo:

import re
res = re.sub(r'\d+', lambda x: x.group(0).zfill(5), 'hello120_c')
print(res)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.