In [35]:
# reads a string and returns a masked version of the string,
# where sequences of `length` (default=9) digits are replaced 
# with the replacement character (default='X')
#
# if the string does not fit in memory, we'll need a stream-based approach instead
def mask_digit_sequences(input_str, length=None, replacement=None):
    # this is the recommended way to use default arguments in 
    # python functions
    if length is None:
        length = 9
    if replacement is None:
        replacement = "X"
        
    # i'll use a state-machine approach that counts the number of
    # digits seen in the current sentence
    
    current_sequence = ""
    
    for (i,char) in enumerate(input_str):
        if char.isdigit():
            current_sequence += char
        else: # not a digit
            # broken sequence
            if len(current_sequence) != 0:
                print(current_sequence, end='')
                current_sequence = ""
            else:
                print(char, end='')
        
        if len(current_sequence) == length:
            for i in range(length):
                print(replacement, end='')
            current_sequence = ""
        
        # we've reached the end of the string and the current sequence is not empty
        if i == len(input_str) -1 and len(current_sequence) != 0:
            print(current_sequence,end='')

In [36]:
mask_digit_sequences("12")


12

In [37]:
mask_digit_sequences("aaaa12345678bbbbb1234567890123")


aaaa12345678bbbbXXXXXXXXX0123

In [39]:
mask_digit_sequences("aaaa12345678bbbbb1234567890123",replacement='-')


aaaa12345678bbbb---------0123

In [40]:
mask_digit_sequences("Claudio’s number is 123456789 and his friend’s number is 12345678900033322255")


Claudio’s number is XXXXXXXXX and his friend’s number is XXXXXXXXXXXXXXXXXX55