0

I have this input string:

string = '''p1 = {
s,
},

p2 = {
{s,
},

p3 = {
s,
},

p2 = {
}s,
},'''

I am trying to replace all paragraphs starting with p2 = { and ending with }, and end up with this new expected output string:

p1 = {
s,
},

p3 = {
s,
},

I can achieve this without using a regex by just looping over the lines. But how would I do it with a regex?

This method using re.subn does not make any replacement and I don't understand why not:

import re
repl = ''
pattern = r'p2 = {.*?},'
new_string, number_of_subs_made = re.subn(pattern, repl, string, 
re.MULTILINE|re.DOTALL)

This method using re.findall seems to be able to find all matches:

import re
pattern = r'.*?(p2 = {.*?},).*?'
m = re.findall(pattern, string, re.MULTILINE|re.DOTALL)
print('\n'.join(m))

It prints this output:

p2 = {
{s,
},
p2 = {
}s,
},

There is a question on how to emulate grep -v and exclude lines with pattern matches, and the answer suggests using a negative lookahead: Regular expression to match a line that doesn't contain a word?

And there is a question on how to use negative lookahead across multiple lines here: Regex with negative lookahead across multiple lines

Would it perhaps be possible to somehow invert that negative lookahead and print the lines that do not match?

tommy.carstensen
  • 8,962
  • 15
  • 65
  • 108
  • 1
    You should use `re.subn(pattern, repl, string, flags=re.MULTILINE|re.DOTALL)` or `re.subn(pattern, repl, string, 0, re.MULTILINE|re.DOTALL)`. Also, the pattern might be made a bit safer with anchors: `pattern = r'^p2 = {.*?},$'`. – Wiktor Stribiżew Nov 22 '17 at 11:27
  • Thanks @WiktorStribiżew. I ended up with this `new_string, number_of_subs_made = re.subn(re.compile(pattern, re.MULTILINE|re.DOTALL), repl, string)` once I looked at the question, which this was marked as a duplicate of. I hadn't noticed the `count` going before the `flags`. Thanks. – tommy.carstensen Nov 22 '17 at 11:31

0 Answers0