2016-12-22 30 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

相關問題