Regex 在Perl中使用grep

Regex 在Perl中使用grep,regex,perl,Regex,Perl,我有下面的代码片段。我需要在适当的位置插入一个grep命令,以便只查找80到89之间的等级,并将它们存储在名为@GradeB的单独数组中。我试过使用@GradeB=grep(“8[0-9]”,@Grades),但这会将所有内容放入@GradeB。如果我只把80-89分的成绩拿到@GradeB,那我错在哪里呢?为了充分披露,这是家庭作业,但我可以使用任何和所有可用的资源 @Grades = ("Name: Shemp Grade: 82", "Name: Curly

我有下面的代码片段。我需要在适当的位置插入一个
grep
命令,以便只查找80到89之间的等级,并将它们存储在名为
@GradeB
的单独数组中。我试过使用
@GradeB=grep(“8[0-9]”,@Grades),但这会将所有内容放入
@GradeB
。如果我只把80-89分的成绩拿到
@GradeB
,那我错在哪里呢?为了充分披露,这是家庭作业,但我可以使用任何和所有可用的资源

@Grades = ("Name: Shemp      Grade: 82",
           "Name: Curly      Grade: 62",
           "Name: Curly Joe  Grade: 58",
           "Name: Joe        Grade: 50",
           "Name: Moe        Grade: 88",
           "Name: Larry      Grade: 82");


# grep command here
print join("\n", @GradeB);

grep
返回表达式计算结果为true的列表中的每个项。表情

"8[0-9]"
是一个字符串,它的计算结果始终为true。您可能打算改用正则表达式:

my @b_grades = grep /Grade: 8[0-9]$/, @grades;
# Alternately, my @b_grades = grep { /Grade: 8[0-9]$/ } @grades;
请注意,我使用了一个比
/8[0-9]/
更具体的正则表达式,它将匹配以下内容:

Name: Inmate 12789132    Grade: 12

这种方法可行,但不是很灵活。正如博罗丁在评论中指出的那样,将正则表达式更改为匹配79到88之间的分数是很困难的。最好提取分数,以便进行数字比较:

my @b_grades = grep {
                        if (/Grade: (\d+)$/)  {
                            $1 if ($1 >= 80 && $1 < 90);
                        }
                    } @grades;
请注意,对于仅由字母、数字和下划线组成的键,引号是可选的。要访问散列中的值,请使用适当命名的
values
函数:

my @grades = values %grades;
像以前一样使用
grep
获取所有B:

my @b_grades = grep { $_ >= 80 && $_ < 90 } values %grades;
print join ',', @b_grades;
# 88,82,82

grep
返回表达式计算结果为true的列表中的每个项。表情

"8[0-9]"
是一个字符串,它的计算结果始终为true。您可能打算改用正则表达式:

my @b_grades = grep /Grade: 8[0-9]$/, @grades;
# Alternately, my @b_grades = grep { /Grade: 8[0-9]$/ } @grades;
请注意,我使用了一个比
/8[0-9]/
更具体的正则表达式,它将匹配以下内容:

Name: Inmate 12789132    Grade: 12

这种方法可行,但不是很灵活。正如博罗丁在评论中指出的那样,将正则表达式更改为匹配79到88之间的分数是很困难的。最好提取分数,以便进行数字比较:

my @b_grades = grep {
                        if (/Grade: (\d+)$/)  {
                            $1 if ($1 >= 80 && $1 < 90);
                        }
                    } @grades;
请注意,对于仅由字母、数字和下划线组成的键,引号是可选的。要访问散列中的值,请使用适当命名的
values
函数:

my @grades = values %grades;
像以前一样使用
grep
获取所有B:

my @b_grades = grep { $_ >= 80 && $_ < 90 } values %grades;
print join ',', @b_grades;
# 88,82,82

您可以结合使用
map()
grep()
。第一个创建arrayref以保留整行和其中的最后一个数字,
grep()
比较它们,最后一个
map()
提取匹配的整行:

#!/usr/bin/env perl

use warnings;
use strict;

my @Grades = ("Name: Shemp      Grade: 82",
           "Name: Curly      Grade: 62",
           "Name: Curly Joe  Grade: 58",
           "Name: Joe        Grade: 50",
           "Name: Moe        Grade: 88",
           "Name: Larry      Grade: 82");


# grep command here

my @GradeB = 
    map { $_->[0] } 
    grep { $_->[1] >= 80 and $_->[1] <= 89 } 
    map { [$_, (split)[-1]] } @Grades;

print join("\n", @GradeB);

您可以结合使用
map()
grep()
。第一个创建arrayref以保留整行和其中的最后一个数字,
grep()
比较它们,最后一个
map()
提取匹配的整行:

#!/usr/bin/env perl

use warnings;
use strict;

my @Grades = ("Name: Shemp      Grade: 82",
           "Name: Curly      Grade: 62",
           "Name: Curly Joe  Grade: 58",
           "Name: Joe        Grade: 50",
           "Name: Moe        Grade: 88",
           "Name: Larry      Grade: 82");


# grep command here

my @GradeB = 
    map { $_->[0] } 
    grep { $_->[1] >= 80 and $_->[1] <= 89 } 
    map { [$_, (split)[-1]] } @Grades;

print join("\n", @GradeB);

查看perldoc的
grep

   grep BLOCK LIST
   grep EXPR,LIST
Grep为
LIST
的每个元素计算
BLOCK
EXPR
,并返回由
BLOCK
EXPR
计算为真值的元素组成的列表。当您指定字符串
“8[0-9]”
(始终为真)时,将返回每个列表元素

您需要将正则表达式作为
EXPR
传递:

@GradeB = grep /8[0-9]/, @Grades;

查看perldoc的
grep

   grep BLOCK LIST
   grep EXPR,LIST
Grep为
LIST
的每个元素计算
BLOCK
EXPR
,并返回由
BLOCK
EXPR
计算为真值的元素组成的列表。当您指定字符串
“8[0-9]”
(始终为真)时,将返回每个列表元素

您需要将正则表达式作为
EXPR
传递:

@GradeB = grep /8[0-9]/, @Grades;

最好不要在词汇变量名中使用大写字母

此解决方案的工作原理是提取
等级:
后面的数字字符串,并将其与指定范围进行比较

use strict;
use warnings;

my @grades = (
  "Name: Shemp      Grade: 82",
  "Name: Curly      Grade: 62",
  "Name: Curly Joe  Grade: 58",
  "Name: Joe        Grade: 50",
  "Name: Moe        Grade: 88",
  "Name: Larry      Grade: 82",
);

print "$_\n" for grep {
  /grade\s*:\s*(\d+)/i and $1 >= 80 and $1 < 90;
} @grades;

最好不要在词汇变量名中使用大写字母

此解决方案的工作原理是提取
等级:
后面的数字字符串,并将其与指定范围进行比较

use strict;
use warnings;

my @grades = (
  "Name: Shemp      Grade: 82",
  "Name: Curly      Grade: 62",
  "Name: Curly Joe  Grade: 58",
  "Name: Joe        Grade: 50",
  "Name: Moe        Grade: 88",
  "Name: Larry      Grade: 82",
);

print "$_\n" for grep {
  /grade\s*:\s*(\d+)/i and $1 >= 80 and $1 < 90;
} @grades;

很好的一点,是的,是的,我刚刚更新了主要帖子这样说。
“8[0-9]”
是一个既不是
也不是
“0”
的字符串。因此,它总是正确的。
grep
检查列表中的每个值。你能证明你能从一个字符串中找到分数的值吗?很好,是的,我刚刚更新了主要帖子这么说。
“8[0-9]”
是一个既不是
也不是
“0”
的字符串。因此,它总是正确的。
grep
检查列表中的每个值。你能证明你能从一个字符串中找到分数的值吗?这有点破坏了教程。如果名称fieldAh中有数字,它也可能不起作用,这正是我所需要的。我没有意识到我需要
/
来让它识别为regex。谢谢大家!@瓦恩迪尔:如果你在写考试代码,我一定要以乔90的身份登录!更新!今年A级通行证较少,因此B级已改为79至88级。“你能快点修好你的课程吗?”博罗丁伤心地说,分数膨胀是一个真正的问题,而不仅仅是一个假设。看看我的最新编辑。这有点破坏了教程。如果名称fieldAh中有数字,它也可能不起作用,这正是我所需要的。我没有意识到我需要
/
来让它识别为regex。谢谢大家!@瓦恩迪尔:如果你在写考试代码,我一定要以乔90的身份登录!更新!今年A级通行证较少,因此B级已改为79至88级。“你能快点修好你的课程吗?”博罗丁伤心地说,分数膨胀是一个真正的问题,而不仅仅是一个假设。查看我的最新编辑。我没有意识到我需要
/
来让它识别它是regex,这是我的问题。非常感谢。我没有意识到我需要
/
来让它识别它是regex,这是我的问题。谢谢大家!-1为严重不必要的并发症。这可能是非常危险的