我是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.
我无法理解它能是什么。
答案 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处理。