2016-12-22 35 views
2

我是新用Perl,我已经面临这个问题:全局符号“@str”需要明确的包名

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

一段代码,导致此消息,可以作为一个PROGRAMM,但不起作用。这是它:

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. 

这个输出,我只是不明白那是什么。

+2

该代码通过执行'$ str [$ indexOfSub ...]'隐式使用'@ str'。显然,程序和子程序的使用方式并不相同,可能是因为在任何驱动器中使用“严格的”。请添加'use strict;'并声明一切。并且绝对地使用警告; – zdim

+0

zdim,谢谢:)你的回答不是一个解决方案,但它使这个问题更清晰。我添加了使用scrict,在程序中遇到了同样的错误。现在我明白我的代码在语法上是不正确的(我错误地处理了这些行的字母),所以需要用它代替 – Fruling

+1

,所以需要替换'$ str [$ indexOfSub + length($ substr)] = ='?''用'substr($ str,$ indexOfSub + length($ substr),1)=='?''只有 – Fruling

回答

4

这是因为perl字符串不是像某些语言中的字符数组。因此$str[3]不是访问$str的有效方式。但是,它会访问@str的第三个元素,该元素不存在并且尚未声明,因此是警告。

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

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

我建议你实际上想要做的是:

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

\b是“字边界” Perl的正则表达式,因此将匹配标点符号或空格的东西,虽然它不是严格的相当于你在做什么(有一大堆更多的标点符号可以工作)。

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

+0

啊,一个很好的抓住:) – zdim

+0

是的!是的,它是:)非常感谢你 – Fruling

+3

'$ containsSub = $ str =〜m/\ b \ Q $ substr \ E \ b /' – Borodin

相关问题