I need to repeatedly replace all occurrence of 00000
with 0
in a binary string input.
Although I'm able to achieve it to some extent, I do not know the logic when there are multiple consecutive 00000s like for example:
- 25 0s should be replaced with one 0
- 50 0s should be replaced with two 0s
- 125 0s should be replaced with one 0
Currently I have following code :
new_list = []
c = 0
l = list(s.split("00000"))
print(l)
for i in l:
if i == "00000":
for x in range(l.index(i),l.index(i-3)):
if l[x] != 0:
break
for y in range(0,5):
del l[i-y]
new_list.append(i)
new_list.append("0")
r_list = new_list[0:-1]
r_list= ''.join(map(str, r_list))
print(r_list)
But this will not work for 25 0s. Also What would be the regex alternative for this ?
CodePudding user response:
To get those results, you would need to repeatedly replace five consecutive zeroes to one zero, until there is no more occurrence of five consecutive zeroes. Here is an example run:
s = "0" * 125 # example input
while "00000" in s:
s = s.replace("00000", "0")
print(s)
CodePudding user response:
As I state in my comment, my best guess at what you're trying to do is that you're trying to repeatedly apply the rule that 50
's get replaced with 1, so that, for example, 25 0
's get reduced to 00000
, which in turn gets reduced to 0
. Assuming that's correct:
It's not the most efficient approach, but here's one way to do it:
import re
new = "00000100002000003000000004" "0"*50
old = ""
while old != new:
old,new = new,re.sub("0{5}","0",new)
print(new) #0100002030000400
Alternatively, here's a method to apply that change in one pass through the array:
s = "00000100002000003000000004" "0"*50
stack,ct = ['#'],[-1]
i = 0
while i < len(s):
if s[i] == stack[-1]:
ct[-1] = 1
i =1
elif ct[-1] >= 5:
q,r = divmod(ct[-1],5)
ct[-1] = q r
else:
stack.append(s[i])
ct.append(1)
i =1
while ct[-1] >= 5:
q,r = divmod(ct[-1],5)
ct[-1] = q r
ans = "".join(c*k for c,k in zip(stack[1:],ct[1:]))
print(ans)
CodePudding user response:
PyPI regex supports recursion. Something like this could do:
import regex as re
s = re.sub(r"0000(?:(?0)|0)", "0", s)
See this Python demo at tio.run or the regex demo at regex101
At (?0)
or alternatively (?R)
the pattern gets pasted (recursed).