1

Assume there's a string

"An example striiiiiing with other words"

I need to replace the 'i's with '*'s like 'str******ng'. The number of '*' must be same as 'i'. This replacement should happen only if there are consecutive 'i' greater than or equal to 3. If the number of 'i' is less than 3 then there is a different rule for that. I can hard code it:

import re
text = "An example striiiiing with other words"
out_put = re.sub(re.compile(r'i{3}', re.I), r'*'*3, text)
print(out_put)

# An example str***iing with other words

But number of i could be any number greater than 3. How can we do that using regex?

Rabindra
  • 369
  • 4
  • 14
  • 1
    Trivially, `re.sub("iiiiii", "******", string)`. Can you explain your question a bit better? Is it only "i"? is it any repeating letters? Any repeated characters? Is it any six characters starting from the fourth one?... – Amadan Oct 14 '21 at 11:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238139/discussion-between-rabindra-and-wiktor-stribizew). – Rabindra Oct 14 '21 at 11:58

1 Answers1

3

The i{3} pattern only matches iii anywhere in the string. You need i{3,} to match three or more is. However, to make it all work, you need to pass your match into a callable used as a replacement argument to re.sub, where you can get the match text length and multiply correctly.

Also, it is advisable to declare the regex outside of re.sub, or just use a string pattern since patterns are cached.

Here is the code that fixes the issue:

import re
text = "An example striiiiing with other words"
rx = re.compile(r'i{3,}', re.I)
out_put = rx.sub(lambda x: r'*'*len(x.group()), text)
print(out_put)
# => An example str*****ng with other words
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563