perl脚本的限制效果

时间:2017-01-15 13:20:51

标签: perl

我想在tex文档上运行perl脚本,但不在序言中运行。 如何限制它对某个模式下的文件部分的影响(例如^\\begin\{document\}$)?这是脚本:

# Insert the macro \gr{} around Greek passages.

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

my $L = qr/[^A-Za-z]/;
my $g = qr/\p{Greek}/;

local $/;           # slurp
$_ = decode('utf-8', <>);

# Remove already existing instances.
s/\\gr
(               # 1
 {
  (             # 2
   (?: \\.          # 3. escaped chars
     | [^{}]
     | (?1)         # recur to 1
   )*
  )  
 }
)
/$2/xg;

# Insert new.
s/(
  [([]*             # begin with puncuation?
  $g                # Greek;
  ($L|\\\w+)*       # contain any non-Latin char or cmd;
  $g                # end with Greek
  [)\]]*            # and puncuation?
  )
/\\gr{$&}/xg;

print encode('utf-8', $_);

1 个答案:

答案 0 :(得分:6)

local $/可用于除完全啜食之外的其他事物。 $/是输入记录分隔符,perl读取所有内容,包括输入记录分隔符,然后将其作为返回。 $/的默认值是换行符"\n"

如果将输入记录分隔符设置为undef,则(以某种方式)perl将永远不会在文件中找到输入记录分隔符,因此您将整个文件作为返回。但您可以将输入记录分隔符设置为您想要的任何内容......

$ cat data.txt
I don't want to proccess 
this part of the file.
\begin{document}
I just want to process
the stuff down here.
\begin{document}
hello
use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

my $fname = 'data.txt';
open my $INFILE, '<', $fname;

my ($unprocessed, $needs_processing);

{
    local $/ = "\\begin{document}\n";
    $unprocessed = <$INFILE>;
    $/ = undef;  #Read rest of file no matter what it contains.
    $needs_processing = <$INFILE>;
}

close $INFILE;

print $unprocessed;
say '-' x 10;
print $needs_processing;

--output:--
I don't want to proccess 
this part of the file.
\begin{document}
----------
I just want to process
the stuff down here.
\begin{document}
hello

如果您想对文件进行原位编辑:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

my $fname = 'data.txt';
my $divider = "\\begin{document}\n";
my $backup = '.bak';

open my $INFILE, '<', $fname;

{
    local ($^I, $/, @ARGV) = ($backup, $divider, $fname);

    CHUNK:
    while(<>) {

        if($. == 1) {    # $. is the line number (starts at 1)
            print;       #STDOUT has been redirected to the file 'data.txt'.
            $/ = undef;  #Read rest of file no matter what it contains.
            next CHUNK;
        }

        #Process $_ here:
        s/e/E/g;

        print;  #STDOUT has been redirected to the file 'data.txt'.
    }

}

close $INFILE;
$ cat data.txt
I don't want to proccess 
this part of the file.
\begin{document}
I just want to procEss
thE stuff down hErE.
\bEgin{documEnt}
hEllo

原始文件将位于data.txt.bak。如果您不想备份,请将空字符串分配给$^I

请注意,在您的代码中,语句为:

local $/;

没有做任何有用的事情。在您的代码中,该语句不在块内(=由大括号包围的代码的一部分)。 local $/说:

  1. $/的原始值隐藏在某处。
  2. 将undef分配给$/
  3. 退出包含local $/的数据块时,请将原始值指定给$/
  4. 但是因为local $/;不在代码中的某个块中,所以不会退出任何块,并且永远不会恢复$/的原始值。因此,隐藏$/的原始值没有意义。