64

I have strings that contain a number somewhere in them and I'm trying to replace this number with their word notation (ie. 3 -> three). I have a function that does this. The problem now is finding the number inside the string, while keeping the rest of the string intact. For this, I opted to use the re.sub function, which can accept a "callable". However, the object passed to it is the internal _sre.SRE_Match and I'm not sure how to handle it. My function accepts a number or its string representation.

How should I write some helper function which can be used to bridge the re.sub call with my function doing the required processing? Alternatively, is there a better way to do what I want?

Nmk
  • 1,281
  • 2
  • 14
  • 25
VPeric
  • 7,391
  • 6
  • 21
  • 17
  • 7
    With a `_sre.SRE_Match`, you can call `.group()` on it to get the groupped items. Is this what you need? – TerryA Sep 11 '13 at 09:49

3 Answers3

80

You should call group() to get the matching string:

import re

number_mapping = {'1': 'one',
                  '2': 'two',
                  '3': 'three'}
s = "1 testing 2 3"

print re.sub(r'\d', lambda x: number_mapping[x.group()], s)

prints:

one testing two three
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
30

To make your function fit with re.sub, you can wrap it with a lambda:

re.sub('pattern', lambda m: myfunction(m.group()), 'text')
glglgl
  • 89,107
  • 13
  • 149
  • 217
7

A solution without lambda

import re

def convert_func(matchobj):
    m =  matchobj.group(0)
    map = {'7': 'seven',
           '8': 'eight',
           '9': 'nine'}
    return map[m]

line = "7 ate 9"
new_line =  re.sub("[7-9]", convert_func, line)
Rob Kwasowski
  • 2,690
  • 3
  • 13
  • 32
user984003
  • 28,050
  • 64
  • 189
  • 285