In Perl, how to “jump over” certain text and do se

2020-05-10 02:03发布

The text has many occurrences of pattern; while doing regex find-and-replace, I wanna jump over certain segments of the text, and replace pattern in the remaining part. Example, in the code:

#!/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(updated 16.2.23) The criteria for replace/no replace is as follows: (1) START and END may be on one line or span multiple lines, all patterns within this range should NOT be replaced;

(2) . and pattern may or may not have spaces, tabs, newlines between them, the first occurrence of pattern after . should be replaced;

(3) comments will always just be one line starting with //; do not consider /* ... */ style of comments for the time being.

(4) // may or may not be the first character of a line; so it is with ..

Anything between START_FLAG and END_FLAG, or anything within a comment, should be ignored; and, if the pattern follows a ".", it should also be ignored. patterns in the remaining part of the text should be replaced by new stuff. I tried to use s/START.*?END|\/\/.*?\n|.\s*\w+|\w+//g stuff, but just cannot reach a solution.

This seems little bit convoluted for me; any help? Thx in advance :-)

1条回答
smile是对你的礼貌
2楼-- · 2020-05-10 02:36

Use normal if statement would do:

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

NOTE Above is the answer prior to the OP's edit 16.2.22.

查看更多
登录 后发表回答