简体   繁体   中英

Replace segment of text, across multiple lines between two strings - regex

I am currently struggling to get my regex to match both everything between two strings and then match multiple lines inside of this first match.

So I am trying to go from this

if
{
  // A comment 
  foo(c.AAA);
  bar(c.AAA);
  foobar(c.AAA);
}
else 
{
  foo(c.AAA);
  bar(c.AAA);
  foobar(c.AAA);
}

To this

if
{
  // A comment 
  foo(c.BBB);
  bar(c.BBB);
  foobar(c.BBB);
}
else 
{
  foo(c.AAA);
  bar(c.AAA);
  foobar(c.AAA);
}

I am able to match everything between the comment and the word ELSE.

But I then want to be able to Match "c.AAA" and replace it with "c.BBB" in a bulk way.

Any Help would be appreciated!

Edit: For clarity I just wanted to add that the code I am specifically using is c# and the find and replace is happening across a large number of files. I didn't mention it earlier as I am still interested in finding if this is possible with regex

Refactor your code

auto arg = c.AAA;
if (xyz) {
  arg = c.BBB;
}
foo(arg);
bar(arg);
foobar(arg);

Edit

For C# you could write

var arg = c.AAA;
if (xyz) {
  arg = c.BBB;
}
foo(arg);
bar(arg);
foobar(arg);

Edit 2

It can be done with Regex but I could not get it working with VSC.

With Notepad++ the regex search with negated character set includes the newline.

In Notepad++ you have Find in Files in the Find/Replace dialog and it shows the number of replacements made in the files. Select the checkbox Follow current doc and maybe In all sub-folders

Find: (// A comment[^}]+?)c\\.AAA

Replace: \\1c.BBB

Search Mode: Regular Expression

Apply this Find/Replace until the number of replacements is 0

I don't know of a method to achieve this with a single regex, but you could get it done with a small Python script. First, you would split your text into chunks using the two strings as delimiters:

import re

text = """if
{
  // A comment 
  foo(c.AAA);
  bar(c.AAA);
  foobar(c.AAA);
}
else 
{
  foo(c.AAA);
  bar(c.AAA);
  foobar(c.AAA);
}
"""

chunks = re.split(r'(// A comment|else)', text)

Which would give:
['\\nif\\n{\\n ', '// A comment', ' \\n foo(c.AAA);\\n bar(c.AAA);\\n foobar(c.AAA);\\n}\\n', 'else', ' \\n{\\n foo(c.AAA);\\n bar(c.AAA);\\n foobar(c.AAA);\\n}\\n']

And then you can use a loop to modify the part between the delimiters and produce the final string:

output = chunks[0]
prev = chunks[0]
for c in chunks[1:]:
    if prev == "// A comment":
        c = c.replace("c.AAA", "c.BBB")
    output += c
    prev = c

print(output)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM