+ 2
I need to insert 0 after k times 1 using REGEX. n,k=map(int, input ().split());l=input ().strip() print(sub(f'1{k}',????
Ex input: 5,2,11001 , output: 110001 , here 1 has occurred k times(k=2). Hence, I need to replace 0 after it.
17 Answers
+ 7
Tibor Santa Awesome point!
I hadn't even considered the regex pattern: "1{2}" where the number in the bracket denotes the exact number of times the preceding character must appear.
For those who might still struggle mentally processing the line below:
f"1{{{k}}}"
Think of it as follow:
"1{" + str(k) + "}"
Another way to break this down is to see f"1{{{k}}}" as the following 3 strings being concatenated:
f"1{{" + f"{k}" + f"}}"
Doubling up the curly brackets in the 1st and 3rd strings is the same as escaping the pair into a single character.
f"1{{" => "{"
and
f"}}" => "}"
The 2nd string will interpolate the value of "k" into the string template. Therefore, "{k}" => "2".
Putting it altogether reveals:
"1{" + "2" + "}" => "1{2}"
+ 8
Russ I want to thank you for clarifying the reason for using a lambda. This forced me to do some digging to find a way to improve the solution. In the process, I learned about an alternative to using backreferences like \1 and lambdas - which you might find interesting.
First, for a simple improvement, the pattern used in your solution can be simplified since it's not using any capture group parenthesis:
f'{"1"*k}' => "1"*k
Next, and more interestingly, the lambda can be replaced with using a symbolic group by number:
lambda m: m.group(0) + '0' => '\g<0>0'
You can compare the original and simplified versions below:
Original (using lambda):
----
re.sub(f'{"1"*k}', lambda mo: mo.group(0) + '0', string)
----
Simplified (using symbolic group name):
----
re.sub("1"*k, '\g<0>0', s)
----
You can also use a named capture group with this approach:
----
re.sub(f'(?P<grpA>{"1"*k})', '\g<grpA>0', s)
----
I provide more details in this code below with examples.
- https://code.sololearn.com/cMpNMvM6jjrN
+ 6
The details for this question doesn't make sense.
For the input: 5, 2, 11001
What is the usage of the first two values: 5 and 2?
Why exactly was an extra 0 placed in the output?
How exactly is RegEx meant to be used here?
+ 6
Mndm
Regarding: f'"1"{k}'
For: k = 2
The pattern would be:
"1"2
Which includes characters for double quotes and the number 2.
This would not match any examples provided which contain only 0s and 1s.
Basically, f'"1"{k}' is concatenating 2 different string values.
However, f'"1"*{k}' is concatenating the same string ("1") a multiple of {k} times.
+ 5
Mndm In all your examples, the first input value matches the number of digits in th he 3rd input value.
What are the expected outputs if the length values did not match the string lengths?
+ 5
One more trick that allows to use f-string in the pattern.
re.sub(f"1{{{k}}}", "\g<0>0", s)
For example if k=2 we want the regex pattern 1{2} with the number in the braces to be dynamic. To achieve that with f-string, we need to escape the braces, by actually doubling them. Then we put the k in braces so its value is inserted. Hence we end up with triple braces...
+ 4
Can you provide a few more input / output examples? Something is still not making sense for me.
+ 4
This is the best I can do:
import re
k = 2
string = '1110001110110'
print(re.sub(f'{"1"*k}', lambda mo: mo.group(0) + '0', string)) # 1101000110101100
+ 3
x = 2
print(f"x is equal to {x}.") # prints "x is equal to 2."
This example demonstrates that the curly brackets are not kept in the format string. In your original code, you had f'1{k}' which is the string '12' (if k is 2), not '1{2}' that you would require for the regex to work.
In my code, f'{"1"*k}' means that string "1" is concatenated k times (as David Carroll explained), and the result in inserted into the format string. This means that f'{"1"*k} is "11" if k is 2, "111" if k is 3, etc.
My code then replaces "11" with "110", or "111" with "1110" as required.
+ 2
David Carroll
1. input: 10 2
1110111001
Output: 110101101001
We need to place 0 after 1 has appeared after 2 times, because the value of k is 2.
2. input: 15 3
110111011111000
Output: 11011100111011000
Here we need to insert 0 after k has appeared 3 times.
+ 2
It is a little tricky to add the "0" after the "1"s. Normally I would replace using the number of the capture group (0 in this case), but doing that means saying r"\0" + "0" (r"\0" returns capture group number 0, and + "0" to add the extra "0"), but this results in the string "\00", which doesn't work. The workaround is using lambda.
When you use lambda in the replacement string, the match object is passed to it (hence why I use the letters "mo"). Then it is a case of getting mo.group() (which is the "1"s it matched) and adding the "0".
Of course,
print(re.sub(f'{"1"*k}', f'{"1"*k}0', string))
would have worked too.
I hope that makes sense.
+ 2
David Carroll Thank you for looking further into this. The '\g<0>' notation is news to me and it will definitely come in handy in the future. Thanks also for pointing out my boneheaded mistake in using f'{"1"*k}' over simply "1"*k ๐๐คฆโโ๏ธ
Tibor Santa Thank you for your hint on format strings. I didn't know that double curlies escaped to a single curly so that's something else I learnt this morning.
All in all, a really interesting discussion - thank you. Interesting question Mndm
+ 1
David Carroll . 5 is the length of string , so the string contain 11001. 2 is the no.of 1s after which a zero is to be placed. In the stirng '11001' there are 2 ones consecutively. So a zero is to placed after it.
+ 1
It will match David Carroll
0
Russ can you explain your code pls
0
Russ for finding the consecutive ones pattern why f'"1"{k}' is not working..??