Как использовать регулярные выражения (регулярное выражение) для изменения всех вхождений строки, следующих за другой строкой (макрос Notepad )?

#regex #replace #macros #notepad #regexp-replace

Вопрос:

В следующем минимально воспроизводимом примере я хочу сделать все слова в разделе [bar] строчными:

 [foo]
foo1=Hello World
[bar]
bar1=Hello World
bar2=Worldly Hello
 

Желаемый результат -:

 [foo]
foo1=Hello World
[bar]
bar1=hello world
bar2=worldly hello
 

Для этого я использую регулярное выражение (регулярное выражение) (.*?[bar].*?)([A-Z]) со строкой замены $1L$2 .

В Notepad я включаю регулярное выражение в диалоговом окне Поиск и замена, а также включаю параметры Match case и. . matches newline

При этом выполнение Replace операции работает должным образом. Затем я могу многократно нажимать Replace кнопку в Notepad снова и снова, пока не достигну EOF цели, чтобы выполнить работу.

Итак, теперь, когда это работает, я хочу создать многоразовый макрос Notepad , чтобы покончить с утомительностью и выполнить операцию со всем файлом.

Моя первая идея состояла в том , чтобы просто использовать Replace All , но это не сработает, потому что каретка регулярного выражения не сбрасывается после каждой операции замены при использовании Replace All .

Как можно улучшить мое регулярное выражение, чтобы заменить все [bar] строки разделов строчными значениями и заставить его работать в макросе Notepad ?

Если нет возможности улучшить мое регулярное выражение, я готов использовать другой метод макросов Notepad для выполнения этой задачи.


Следующее предназначено в качестве контекста и не требует чтения. Как только я пойму, как это сделать, я смогу адаптировать то, что я узнаю, к следующему более сложному случаю. Но если вы предпочитаете сосредоточиться на этом более сложном деле, это тоже здорово.

Я значительно упростил ситуацию для приведенного выше примера. В моих фактических входных файлах есть несколько [sections] до и после [bar] раздела. Кроме того, я хочу применять строчные буквы только к первой букве всех слов, которые не являются первым словом в строке. Тем не менее, у меня есть рабочий код для выполнения всего этого, поэтому, если я получу значительно упрощенный пример (выше), работающий в макросе, у меня не должно возникнуть проблем с адаптацией его для гораздо более сложного случая в реальном мире.

Если вас интересует более сложный случай в реальном мире, вот пример ввода:

 [foo]
foo1=Hello World
[bar]
bar1=Hello World
bar2=Worldly Hello
bar3=Worldly-Hello
bar4=worldly Hello
[baz]
baz1=Hello World
 

вот желаемый результат:

 [foo]
foo1=Hello World
[bar]
bar1=Hello world
bar2=Worldly hello
bar3=Worldly-hello
bar4=worldly hello
[baz]
baz1=Hello World
 

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

1. Это помогло бы вашему вопросу также показать, каков ожидаемый результат.

2. @TimBiegeleisen Также добавил более сложный случай в реальном мире с примерами входных и выходных данных, если вам интересно.

3. Ваш второй пример ввода и вывода кажется мне идентичным.

4. @TimBiegeleisen Я не знаю, что тебе сказать. Может быть, новые очки? Запустите a diff , чтобы увидеть различия?

5. 2 текста в конце вашего вопроса идентичны.

Ответ №1:

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

Вы можете сопоставить все слова после [bar] заголовка раздела и после каждого слова, за которым следует = использование

Найти Что: (?:G(?!^)|^[bar])(?:s*Rw =|[^wrn] )Kw
Заменить На: L$0

Смотрите скриншот демонстрации и настроек регулярных выражений:

введите описание изображения здесь

Сведения о регулярном выражении

  • (?:G(?!^)|^[bar]) — одно из двух: конец предыдущего совпадения ( G(?!^) ) или ( | ) [bar] слово ( [bar] ) в начале строки ( ^ )
  • (?:s*Rw =|[^wrn] ) — ноль или более пробелов, последовательность разрывов строк, один или несколько символов слов, = ( s*Rw = ) или ( | ) любой один или несколько символов, отличных от символов слов, CR и LF ( [^wrn] )
  • K — оператор сброса соответствия, который удаляет весь текст, сопоставленный до сих пор, в общий буфер памяти соответствия
  • w — один или несколько символов слова ( $0 указывает на это значение).

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

1. О, ничего себе. Огромное спасибо. Мне нужно тщательно изучить ваш ответ и поэкспериментировать с ним, но я думаю, что это именно то, чего я хотел. Если у вас есть время разобрать регулярное выражение и немного объяснить каждый раздел, это будет наиболее полезно. Еще раз спасибо вам.

2. лол. Великие умы мыслят одинаково. 😉 Пока я писал комментарий, вы редактировали свой ответ, чтобы предоставить именно то, что требовал мой комментарий. Спасибо.

3. @RockPaperLz-MaskitorCasket Хорошо, если подумать, это можно еще больше упростить до (?:G(?!^)|^[bar])(?:s*Rw =|[^wrn] )Kw

4. Ах! Я вижу, что ты делаешь. Два места, где у меня возникли проблемы: (1) G(?!^) всегда ли заканчивается предыдущий матч? (2) Какую ссылку вы использовали для изучения, которая K доступна для использования в движке регулярных выражений Notepad ?

5. Кроме того, я довольно много прочитал о рекурсии регулярных выражений, прежде чем опубликовать свой вопрос, потому что подумал, что, возможно, смогу его использовать. Мое первоначальное прочтение вашего ответа состоит в том, что он технически не использует рекурсию. Вы бы согласились?