Как в Perl перепрыгнуть через определенный текст и выполнить поиск и замену в оставшейся части?

В тексте много раз встречается pattern; выполняя поиск и замену регулярных выражений, я хочу перепрыгнуть через определенные сегменты текста и заменить pattern в оставшейся части. Пример в коде:

#!/usr/bin/env perl
use strict;
use warnings;

#iterate the DATA filehandle
while (<DATA>) {
    # This one replaces ALL occurrences of pattern.
    s/old/new/gs;
    # How do I skip the unwanted segments and do the replace?
    #print all
    print;
}

##inlined data filehandle for testing. 
__DATA__
START xx old xx END     --> within boundaries,  should NOT replace
START xx old
      xx old xx END     --> within boundaries,  should NOT replace
// xx old               --> within comment,     should NOT replace
xx // xx old            --> within comment,     should NOT replace
. old old xx            --> following a point,  should NOT replace
                            first one, just replace second one
xx .
  old
  old xx                --> following a point,  should NOT replace first
                            one, just replace second one.
xx old xx               --> other scenarioes,   should REPLACE

EDIT 16.2.22 (обновлено 16.2.23) Критерии для замены/без замены следующие: (1) START и END могут находиться в одной строке или охватывать несколько строк, все pattern в этом диапазоне должны НЕ подлежит замене;

(2) . и pattern могут иметь или не иметь пробелов, табуляции, новой строки между ними, первое вхождение pattern после . должно быть заменено;

(3) комментарии всегда будут состоять из одной строки, начинающейся с //; пока не рассматривайте /* ... */ стиль комментариев.

(4) // может быть или не быть первым символом строки; так и с ..

Все, что находится между START_FLAG и END_FLAG или что-либо внутри комментария, следует игнорировать; и, если pattern следует за ".", его также следует игнорировать. patterns в оставшейся части текста заменить на новый материал. Я пытался использовать s/START.*?END|\/\/.*?\n|.\s*\w+|\w+//g, но не нашел решения.

Это кажется мне немного запутанным; любая помощь? Спасибо заранее :-)


person katyusza    schedule 22.02.2016    source источник
comment
Благодаря предложениям того, кто помог ответить на этот вопрос, я понял, что в моем вопросе много неясностей, которые не позволяют полностью охватить все случаи, которые я намеревался охватить. Я просто посмотрю, смогу ли я разместить новый пост с измененным способом выражения моего вопроса.   -  person katyusza    schedule 22.02.2016
comment
Ваш комментарий в коде и EDIT противоречат друг другу. В коде, который вы говорите между START и END, с комментариями, НЕ следует заменять, а в вашем EDIT вы говорите весь шаблон в диапазоне START END и первое вхождение после . следует заменить.   -  person texasbruce    schedule 22.02.2016
comment
@texasbruce Спасибо за внимательное изучение поста, дорогой друг. Я уже обновил пост для согласованности. На самом деле этот пост не очень хороший вопрос; Я уже отправил новый вопрос на click_this_link, и проблема решена. Спасибо еще раз :-)   -  person katyusza    schedule 23.02.2016


Ответы (1)


Используйте обычный оператор if:

while (<DATA>) {
  next if (m/^START/ && m/END$/ ) ||  m/^\/\// || m/^\./;
  s/old/new/gs;
  print;
}

ПРИМЕЧАНИЕ Выше приведен ответ до редактирования OP 16.2.22.

person texasbruce    schedule 22.02.2016
comment
Кажется, это не решает проблему, приятель~ - person katyusza; 22.02.2016
comment
@katyusza Не кажется? Хотите уточнить? - person texasbruce; 22.02.2016
comment
@texasbruce После извлечения дополнительной информации из ОП быстро стало ясно, что вопрос не так прост, как кажется, и что для правильного решения потребуется полноценный синтаксический анализатор. Поскольку мне не хотелось брать на себя такой объем работы только для того, чтобы ответить на вопрос, я удалил свой упрощенный ответ. Я предлагаю вам сделать то же самое. - person Matt Jacob; 22.02.2016
comment
@MattJacob Вы правы. Он обновил вопрос. Это ответ до обновления. Хотя не удалит. - person texasbruce; 22.02.2016
comment
Друзья, вопрос был решен в новом сообщении, ссылка: stackoverflow.com/questions/35547683/ еще раз спасибо; - ) - person katyusza; 23.02.2016