2016-02-22 7 views
-2

Текст имеет много вхождений pattern; выполняя регулярное выражение find-and-replace, я хочу перепрыгнуть через определенные сегменты текста и заменить pattern на оставшуюся часть. Например, в коде:В Perl, как «перескакивать» по определенному тексту и выполнять поиск и замену в оставшейся части?

#!/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 s в этом диапазоне НЕ должны быть заменены;

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

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

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

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

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

+0

Благодаря предложениям кого-то, кто помог ответить на этот вопрос, я понял, что мой вопрос имеет много двусмысленностей, которые препятствуют полному охвату всех случаев, которые я намеревался охватить. Я просто посмотрю, смогу ли я поставить новый пост с пересмотренным способом выражения моего вопроса. – katyusza

+0

Ваш комментарий в коде и EDIT противоречивый. В коде, который вы указываете между START и END, в комментариях НЕ следует заменять, а в вашем EDIT вы говорите весь шаблон в диапазоне START END и в первом случае после. следует заменить. – texasbruce

+0

@texasbruce Спасибо за ваше тщательное рассмотрение сообщения, дорогой друг. Я уже обновил сообщение для согласованности. На самом деле этот пост не является «хорошим» вопросом; Я уже опубликовал новый вопрос в [click_this_link] (http://stackoverflow.com/questions/35547683/how-to-ignore-parts-of-the-text-and-do-search-and-replace-in-the -remain-part), и он был решен. Спасибо, опять :-) – katyusza

ответ

-1

Использование нормально, если заявление будет делать:

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

Примечание Выше ответ до редактирования Ор в 16.2.22.

+0

Этот, похоже, не решает проблему приятеля ~ – katyusza

+0

@katyusza Кажется? Поразмыслить? – texasbruce

+0

@texasbruce После выдавливания дополнительной информации из OP быстро стало ясно, что вопрос не так прост, как он появился, и что для правильного решения потребуется полномасштабный синтаксический анализатор. Поскольку я не хотел брать на себя эту работу, чтобы ответить на вопрос, я удалил свой упрощенный ответ. Я предлагаю вам сделать то же самое. –