2014-12-05 74 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