2014-12-05 72 views
1

我寫了一個Perl腳本,基本上這樣做:它打開2個非常相似的文本文件。 其實一個是另一個的老版本。舊版本有我想轉移到新版本文本的腳註和邊際註釋。使用未初始化的值連接(。)或字符串test.pl第29行

爲此,我對腳註或邊際音符進行正則表達式搜索,並嘗試在音符前面將單詞用作搜索詞,以便我可以找到音符的正確位置。文本的版本。找到一個搜索詞,我可以使用並不是每一種情況都可能的。

因此,如果我的搜索詞搜索失敗,我仍然需要將註釋轉移到較新的文件(添加errortoken = &xQUADER;)。

以下或多或少只是腳本的問題部分。它在第29行的這個問題的標題中出現警告信息失敗(標記爲:FEHLERzeile)。

LABEL: 
while ($oldscovers =~ /<(f|m)n id="[bkvl0-9]+"\/>/) { 

    $oldscovers =~ s/([a-zA-Z0-9äöüÄÖÜßï<>()"\-]+[.:,;!?]["]| 
[a-zA-Z0-9äöüÄÖÜßï<>()"\-]+ [".:,;!?]| [a-zA-Z0-9äöüÄÖÜßï<>()"\-]+| 
[a-zA-Z0-9äöüÄÖÜßï<>(),"\-]+)(<(f|m)n(id="[bkvl0-9]+"\/>))/$1/; 

    my $searchword = $1; 
    my $transfn = $2; 

    # 
    unless (defined $searchword) { 
     $oldscovers =~ s/(<(f|m)n(id="[bkvl0-9]+"\/>))//; 
     my $transfnfailsearch = $&; 

     # 
     $newelbchap =~ s/(<verse num="${oldscoversnr}">[^ÿ]+<\/verse>)/$1/; 
     my $newelbvers = $1; 
     $newelbvers =~ s/<verse num="${oldscoversnr}">\n//; 
     my $cuttag = $&; 

     # 
     $newelbvers =~ s/<s>/<s>\&xQUADER\;${transfnfailsearch}/; 

     # 
     $newelbvers =~ s/(.+)/${cuttag}$1/; # hier wird $cuttag wieder eingefügt 
     $newelbchap =~ s/<verse num="${oldscoversnr}">[^ÿ]+<\/verse>/${newelbvers}/; 

     # 
     next LABEL; 
    } 

    # 
    # 

    $newelbchap =~ s/(<verse num="${oldscoversnr}">[^ÿ]+<\/verse>)/$1/; 
    my $newelbvers = $1; 

    $newelbvers =~ s/<verse num="${oldscoversnr}">\n//; 
    my $cuttag = $&; 

    if ($newelbvers =~ /${searchword}([ .?!:;,])/) { 
     $newelbvers =~ s/(${searchword})([ .?!:;,])/${searchword}${transfn}$2/; ## FEHLERzeile 
    } 
    elsif ($newelbvers =~ /${searchword}/) { 
     $newelbvers =~ s/${searchword}/${searchword}${transfn}/; 
    } 
    else { 
     $newelbvers =~ s/<s>/<s>\&QUADER\;${transfn}/; 
    } 

    $newelbvers =~ s/(.+)/${cuttag}$1/; # hier wird $cuttag wieder eingefügt 
    $newelbchap =~ s/<verse num="${oldscoversnr}">[^ÿ]+<\/verse>/${newelbvers}/; 
} 

我覺得我得到這個消息,因爲腳本是不是在LABEL重新啓動,被稱爲在unless塊的結尾。

+3

*總是*'使用嚴格;使用警告;'!而一些縮進不會傷害。 – Biffen 2014-12-05 11:43:15

+0

...然後,一旦你沒有錯誤或警告,通過調試器運行它。 – Biffen 2014-12-05 11:48:20

+0

我不得不縮進你的Perl代碼並添加大量空白以便我可以讀取它。你不可能確定你的塊沒有任何佈局。一旦出現問題可能是您的三線替代正則表達式模式。換行符是模式的一部分,除非在對象字符串中找到它們,否則正則表達式引擎將不會找到匹配項。 – Borodin 2014-12-05 12:07:01

回答

0

根據最新評論,我明白出了什麼問題。此行:

while ($oldscovers =~ /<(f|m)n id="[bkvl0-9]+"\/>/) { 

使用一組捕獲圓括號執行正則表達式。當成功時,$1被設置爲匹配的fm$2,$3,$4等被設置爲undef,並且進入循環體。

循環體中的第一件事是大型s///其中包含2組捕獲括號。當它成功時,它將$1$2設置爲捕獲的字符串並將$3,$4等設置爲undef

當大s///無法匹配時,它將保留所有這些捕獲變量,就像以前一樣。 fm仍然在$1undef仍然在$2。既然你沒有測試從$1s///fm的成功或失敗進入$searchword$2undef進入$transfn

你應該做些什麼來解決這個問題是你要如何腳本的行爲,當大s///沒有找到匹配,並寫代碼來執行,如果s///產生一個錯誤的價值思考。

例如,你可以選擇其中之一:

$oldscovers =~ s/.../.../ or next; 
$oldscovers =~ s/.../.../ or last; 
$oldscovers =~ s/.../.../ or die "something bad happened with this string: $oldscovers"; 

,甚至這樣的:

my $searchword; 
my $transfn; 
if($oldscovers =~ s/.../.../) { 
    $searchword = $1; 
    $transfn = $2; 
} 

這將確保$searchword$transfn是民主基金,如果有不匹配。這是另一種方式:

my ($searchword, $transfn) = $oldscovers =~ s/.../.../ ? ($1,$2) :(); 
+0

好的,我明白了!現在知道發生了什麼對避免進一步的問題非常有幫助。非常感謝你!! – LuckyLuke60 2014-12-05 15:35:14