Заменить сегмент текста на несколько строк между двумя строками — регулярное выражение

#c# #regex #visual-studio-code

#c# #регулярное выражение #visual-studio-code

Вопрос:

В настоящее время я изо всех сил пытаюсь заставить мое регулярное выражение сопоставлять все между двумя строками, а затем сопоставлять несколько строк внутри этого первого совпадения.

Итак, я пытаюсь перейти от этого

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

Для этого

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

Я могу сопоставить все между комментарием и словом ELSE.

Но затем я хочу иметь возможность сопоставлять «c.AAA» и массово заменять его на «c.BBB».

Любая помощь будет оценена!

Редактировать: для ясности я просто хотел добавить, что код, который я специально использую, — это c #, а поиск и замена выполняются для большого количества файлов. Я не упоминал об этом ранее, поскольку мне все еще интересно узнать, возможно ли это с помощью регулярных выражений

Комментарии:

1. Вы можете заменить, включив переключатель «найти в выделении»

2. Поиск в выделении очень удобен, но мне нужно сделать это для большого количества файлов, поэтому, к сожалению, это мне здесь не помогает

Ответ №1:

Реорганизуйте свой код

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

Редактировать

Для C # вы могли бы написать

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

Редактировать 2

Это можно сделать с помощью регулярного выражения, но я не смог заставить его работать с VSC.

В Notepad поиск регулярных выражений с отрицаемым набором символов включает в себя новую строку.

В Notepad у вас есть Find in Files Find/Replace диалоговое окно, и оно показывает количество замен, сделанных в файлах. Установите флажок Follow current doc и, возможно In all sub-folders

Найти: (// A comment[^}] ?)c.AAA

Заменить: 1c.BBB

Режим поиска: регулярное выражение

Применяйте эту функцию поиска / замены до тех пор, пока количество замен не станет равным 0

Комментарии:

1. Это кажется хорошим решением, но я внес изменения, чтобы сказать, что я использую c #, поэтому, к сожалению, этот метод decltype не будет работать для меня.

2. @Mi-кратер В C # это называется var arg = C.AAA;

3. Ах да. Я чувствую себя так глупо. Хотя я не делаю это точно так же, как вы, логика та же. Я все еще хочу знать, возможно ли то, что я хотел, с помощью регулярных выражений, но я приму ваш ответ! Большое спасибо!

4. @Mi-krater Я нашел решение с регулярным выражением, но с использованием Notepad

5. Ах, очень умно. Оба ваших варианта кажутся идеальными для того, что я пытался сделать. Большое спасибо, это поможет мне в куче!

Ответ №2:

Я не знаю способа добиться этого с помощью одного регулярного выражения, но вы могли бы сделать это с помощью небольшого скрипта Python. Во-первых, вы должны разделить свой текст на куски, используя две строки в качестве разделителей:

 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)
  

Что даст:
['nifn{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']

А затем вы можете использовать цикл для изменения части между разделителями и получения конечной строки:

 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)