Avatar of jay28lee
jay28lee
 asked on

How do I replace a block of text using regular expressions in Perl?

I have the following subroutine reading the content of a text file template

sub readfile {
   open(INFILE,"$_[0]");
   flock(INFILE,2);
   my @content=<INFILE>;
   flock(INFILE,8);
   close(INFILE);
   return @content;
}

Open in new window


The template contains block of content I would like to replace, from <!--tmpl_start--> to <!--tmpl_end--> where anything can possibly go in between.

It would be easy to use a foreach loop if they are on the same line.

How do I implement this if they're on different lines?
Scripting LanguagesPerlRegular Expressions

Avatar of undefined
Last Comment
jay28lee

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
ozo

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
jay28lee

ASKER
what does this line do?

local $/;
jay28lee

ASKER
another thing, once $content variable is returned, how can i re-assign it to an array variable?

there are other tasks i need to manipulate using the foreach loop and $_ line by line.
SOLUTION
ozo

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
ozo

perldoc perlvar
...
       $/      The input record separator, newline by default.  This
               influences Perl's idea of what a "line" is.  Works like awk's
               RS variable, including treating empty lines as a terminator if
               set to the null string.  (An empty line cannot contain any
               spaces or tabs.)  You may set it to a multi-character string to
               match a multi-character terminator, or to "undef" to read
               through the end of file.  Setting it to "\n\n" means something
               slightly different than setting to "", if the file contains
               consecutive empty lines.  Setting to "" will treat two or more
               consecutive empty lines as a single empty line.  Setting to
               "\n\n" will blindly assume that the next input character
               belongs to the next paragraph, even if it's a newline.
               (Mnemonic: / delimits line boundaries when quoting poetry.)

                   local $/;           # enable "slurp" mode
                   local $_ = <FH>;    # whole file now here
                   s/\n[ \t]+/ /g;

               Remember: the value of $/ is a string, not a regex.  awk has to
               be better for something. :-)

               Setting $/ to a reference to an integer, scalar containing an
               integer, or scalar that's convertible to an integer will
               attempt to read records instead of lines, with the maximum
               record size being the referenced integer.  So this:

                   local $/ = \32768; # or \"32768", or \$var_containing_32768
                   open my $fh, $myfile or die $!;
                   local $_ = <$fh>;

               will read a record of no more than 32768 bytes from FILE.  If
               you're not reading from a record-oriented file (or your OS
               doesn't have record-oriented files), then you'll likely get a
               full chunk of data with every read.  If a record is larger than
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
jay28lee

ASKER
with the modified: return split/^/m,$content;

can i now use the following?

@template = &readfile("$path_to_file");

also, what does the line: open(INFILE,"$_[0]") or die "$_[0] $!";

what does this condition die "$_[0] $!" evaluate?

thanks
ozo

perldoc perlvar
...
       $OS_ERROR
       $ERRNO
       $!      If used numerically, yields the current value of the C "errno"
               variable, or in other words, if a system or library call fails,
               it sets this variable.  This means that the value of $! is
               meaningful only immediately after a failure:

                   if (open(FH, $filename)) {
                       # Here $! is meaningless.
                       ...
                   } else {
                       # ONLY here is $! meaningful.
                       ...
                       # Already here $! might be meaningless.
                   }
                   # Since here we might have either success or failure,
                   # here $! is meaningless.

               In the above meaningless stands for anything: zero, non-zero,
               "undef".  A successful system or library call does not set the
               variable to zero.

               If used as a string, yields the corresponding system error
               string.  You can assign a number to $! to set errno if, for
               instance, you want "$!" to return the string for error n, or
               you want to set the exit value for the die() operator.
               (Mnemonic: What just went bang?)

               Also see "Error Indicators".
jay28lee

ASKER
everything works perfect.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.