全球符号" @ str"需要显式包名称

时间:2016-12-22 09:39:27

标签: perl

我是Perl的新手,我遇到过这个问题:

Global symbol "@str" requires explicit package name (did you forget to declare "my @str"?) at F:\Distrib\LingUtils9\Scripts\CompareLists\CompareLists.pl line 167

导致此消息的一段代码作为程序运行,但不作为子程序工作。这是:

 my $containsSub = 0;
my $str = "This is a string!";
my $substr = "string";
my $indexOfSub = index($str, $substr);
if ($indexOfSub != -1)
{
    if (length($substr)==length($str))
    {
            $containsSub = 1;
    }
    elsif (($indexOfSub == 0)&&(($str[$indexOfSub + length($substr)]=='?')||($str[$indexOfSub + length($substr)]=='!')||($str[$indexOfSub + length($substr)]=='.')||($str[$indexOfSub + length($substr)]==' ')||($str[$indexOfSub + length($substr)]=='\t')))
    {
            $containsSub = 1;
    }
    elsif ((length($str) == $indexOfSub + length($substr))&&(($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]==' ')||($str[$indexOfSub-1]=='\t')||($str[$indexOfSub-1]=='?')||($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]=='!')))
    {
            $containsSub = 1;
    }
    elsif ((($str[$indexOfSub-1]=='?')||($str[$indexOfSub-1]=='!')||($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]==' ')||($str[$indexOfSub-1]=='\t'))||(($str[$indexOfSub+length($substr)]=='?')||($str[$indexOfSub+length($substr)]=='!')||($str[$indexOfSub+length($substr)]=='.')||($str[$indexOfSub+length($substr)]==' ')||($str[$indexOfSub+length($substr)]=='\t')))
    {
            $containsSub = 1;
    }
}
print $containsSub;

这是对行中子行内容的非常原始的验证,并且工作正常。但这(只是copypaste):

sub containsKey 
{
    my $containsSub = 0;
    my $str = "This is a string!";
    my $substr = "string";
    my $indexOfSub = index($str, $substr);
    if ($indexOfSub != -1)
    {
        if (length($substr)==length($str))
        {
            $containsSub = 1;
        }
        elsif (($indexOfSub == 0)&&(($str[$indexOfSub + length($substr)]=='?')||($str[$indexOfSub + length($substr)]=='!')||($str[$indexOfSub + length($substr)]=='.')||($str[$indexOfSub + length($substr)]==' ')||($str[$indexOfSub + length($substr)]=='\t')))
        {
            $containsSub = 1;
        }
        elsif ((length($str) == $indexOfSub + length($substr))&&(($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]==' ')||($str[$indexOfSub-1]=='\t')||($str[$indexOfSub-1]=='?')||($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]=='!')))
        {
            $containsSub = 1;
        }
        elsif ((($str[$indexOfSub-1]=='?')||($str[$indexOfSub-1]=='!')||($str[$indexOfSub-1]=='.')||($str[$indexOfSub-1]==' ')||($str[$indexOfSub-1]=='\t'))||(($str[$indexOfSub+length($substr)]=='?')||($str[$indexOfSub+length($substr)]=='!')||($str[$indexOfSub+length($substr)]=='.')||($str[$indexOfSub+length($substr)]==' ')||($str[$indexOfSub+length($substr)]=='\t')))
        {
            $containsSub = 1;
        }
    }
    return $containsSub;
}
my $keyContains = containsKey();

print $keyContains;

在命令行中输出

Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
3.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
3.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
3.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
3.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
3.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 16
7.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Global symbol "@str" requires explicit package name (did you forget to declare "
my @str"?) at \Compare.pl line 17
1.
Execution of \Compare.pl aborted
due to compilation errors.

我无法理解它能是什么。

1 个答案:

答案 0 :(得分:4)

这是因为perl字符串不是某些语言中的字符数组。

因此$str[3]不是访问$str的有效方式。但是,它将访问@str的第3个元素,该元素不存在且尚未声明,因此警告。

如果您希望按偏移量处理字符串,则需要substr。或my @chars_in_str = split //, $str;

更广泛地说 - 这看起来像是一种相当肮脏的方式尝试和正则表达式匹配。

我建议您实际想要做的是:

if ( $str =~ m/\b$substr\b/ ) { 
    $containsSub = 1;
}

\b是'字边界'的perl-regex,因此会将标点符号或空格匹配,尽管它不是严格等同于你正在做的事情(有一个整体)更多标点符号'''工作')。

你还应该注意 - 如果$substr包含元字符,它们就像正则表达式修饰符一样工作。为避免这种情况,您需要\b\Q$substr\E\b来关闭metachar处理。