2017-01-15 26 views
1

我想在tex-document上運行perl腳本,但不在preamble上運行。 如何限制它對文件部分低於特定模式的影響(例如^\\begin\{document\}$)?這是腳本:perl腳本的限制效果

# 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', $_); 
+0

您可以嘗試將該文件讀入一個字符串,然後使用正則表達式替換丟棄文件的開頭 –

+1

正如@DaveCross所說,沒有代碼示例幫助很不自在;然而,在處理結構化文檔時,Regexp :: Grammars可以幫助您(這些示例完全基於乳膠)。只是一個想法。 –

回答

6

local $/可以用於除了完整的漿液以外的東西。 $/是輸入記錄分隔符,perl會讀取所有輸入記錄分隔符,然後將其作爲返回。 $/的默認值是換行"\n"

如果您將輸入記錄分隔符設置爲undef,那麼(以某種方式)perl將永遠不會在文件中找到輸入記錄分隔符,因此您將整個文件返回爲。但是你可以輸入記錄分隔符設置爲任何你想要的......

​​
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 $/的塊被退出時,將原始值分配給$/

但由於local $/;是不是在你的代碼塊中,無塊將被退出,以及$/原來的值將不會被恢復。因此,存儲$/的原始值沒有任何意義。