在连接(。)中使用未初始化的值或在test.pl第29行使用字符串

时间:2014-12-05 11:34:26

标签: regex perl loops

我编写了一个基本上执行此操作的Perl脚本:它打开了两个非常相似的文本文件。 实际上一个是另一个的旧版本。旧版本有脚注和边注,我想转移到较新版本的文本。

为此,我对脚注或边注进行了正则表达式搜索,我尝试在注释之前使用它作为搜索词,以便我可以找到新版本的注释的正确位置的文字。找到一个我可以使用的搜索词并不是每种情况都可能。

因此,如果我的搜索词搜索失败,我仍然需要将注释转移到较新的文件(添加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块结束时调用。

1 个答案:

答案 0 :(得分: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。由于您没有测试s/// fm$1进入$searchword和{{1}的大undef成功或失败的成功或失败} $2进入$transfn

要解决这个问题,您应该考虑当大s///找不到匹配项时您希望脚本的行为方式,并编写代码来执行此操作{{1}产生假值。

例如,您可以选择其中一种:

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为undef。而这是另一种方式:

$transfn