I was building a script to find credit card numbers in files. For PCI compliance reasons.

I wanted to see and or save the credit card numbers in a file but only parts of them, so I still would be compliant.

So I created this small mask_number function to, well... mask found credit card numbers.

To mask a number with `*`

without masking the first 4 and the last 4 numbers in Python using `re.sub()`

, you can use the following regular expression:

```
import re
def mask_number(number):
return re.sub(r'(?<=\d{4})\d(?=\d{4})', '*', number)
```

The regular expression works as follows:

`(?<=\d{4})`

: Positive look behind to match any digit that has 4 digits behind it`\d`

: Match any single digit`(?=\d{4})`

: Positive lookahead to match any digit that has 4 digits ahead of it

The `re.sub()`

function will replace all the single digits that match the regular expression with the `*`

character.

Example usage:

```
>>> mask_number('1234567890123456')
'1234********3456'
>>> mask_number('1234-5678-9012-3456')
'1234-****-****-3456'
```

In the above example, the function `mask_number()`

takes in a number as a string, and returns a masked string with the first 4 and last 4 digits unmasked and the rest of the digits masked with `*`

.