Bizzare输出来自substr

sud*_*008 0 perl cgi substring

我试图从一个看起来像cs600032016s的代码中提取年份.年份从索引7到10,但只是为了概括它前面的代码的可变长度,我使用了以下代码:

$year = substr($code, $len-5, $len-1);
Run Code Online (Sandbox Code Playgroud)

但它给了我2016s而不是2016年.任何想法错误的地方?更改$len-1$len-2$len-3没有给出改变输出.这很奇怪.这是代码:

sub getCCodeFromCode{
  my ($code) = @_;
  my $len = length($code);
  return substr($code, 0 , $len-5);    #4 char for year and one for sem
}

sub getYearFromCode{
  my ($code) = @_;
  my $len = length($code);
#  print "substr($code, $len-5, $len-1)";
  return substr($code, $len-5, $len-1);
}

sub getSemFromCode{
  my ($code) = @_;
  my $len = length($code);
  return substr($code, $len-1);
}

my %hashmap = &getCourseList;
#my %hashmap = %{$hashmap_ref};

foreach my $key (keys %hashmap) {
  my $code = &getCCodeFromCode($key);
  my $year = &getYearFromCode($key);
  my $sem = &getSemFromCode($key);
  print $key."\n".$code."\n".$year."\n".$sem."\n";
  #print "<p>$key = $hashmap{$key}<br>qq$code b $year b $semqq</p><br>\n";
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

Content-Type: text/html; charset=ISO-8859-1

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Add Assignment</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
cs600172015a
cs60017
2015a
a
cs410012015a
cs41001
2015a
a
cs220012016a
cs22001
2016a
a
cs600442016a
cs60044
2016a
a
cs300022015a
cs30002
2015a
a
cs600032016s
cs60003
2016s
s
cs500022015a
cs50002
2015a
a
cs220012016s
cs22001
2016s
s

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 5

对于文档substr说,这

substr EXPR,OFFSET,LENGTH

从EXPR中提取子字符串并返回它.第一个字符位于零偏移处.如果OFFSET为负数,则从字符串末尾开始.如果省略LENGTH,则返回字符串末尾的所有内容.如果LENGTH为负数,则将多个字符留在字符串末尾.

所以第三个参数是要提取的子字符串的长度,而不是结尾的偏移量

但是,您可以使用负数作为开头和结尾,这将是字符串末尾的索引.像这样

$ perl -E"say substr 'cs600032016s', -5, -1"
Run Code Online (Sandbox Code Playgroud)

产量

2016
Run Code Online (Sandbox Code Playgroud)