如何根据多个条件过滤数组?

How can I filter an array on multiple criteria?

我试图找到所有以 S 和 N 开头的数组元素,但下面的代码无法做到:

@a = qw(sonata Samsung sony icic huawie nissan nokia);

这是我的代码

@filter = grep { (/^s (.*)$/ig) && (/^n(.*)$/ig) } @a;
print "@filter \n";

您走在正确的轨道上,但是您在正则表达式中引入了空格。您还要求字符串以字符 'S' 或字符 'N' 开头的情况,因此您的逻辑是 OR 语句,而不是所写的 AND 语句。如果您只关心第一个字符,那么这就是您的模式中所需要的,并且您想要使用逻辑 OR。

@a = qw(sonata Samsung sony icic huawie nissan nokia);
@filter = grep { /^s/i || /^n/i } @a;
print "@filter \n";

结果:

sonata Samsung sony nissan nokia

编辑 -- 或更简洁地使用一个字符 class

@a = qw(sonata Samsung sony icic huawie nissan nokia);
@filter = grep { /^[sn]/i } @a;
print "@filter \n";

你的问题是逻辑问题。你说你想过滤所有 "start with S and N" 的字符串,但事实并非如此。您想要所有以 S 或 N.

之一开头的字符串

对于 "start with S and N" 的字符串,它的第一个字符必须是 S,并且 也必须是 N,这是不可能的。

表达式

grep { (/^s (.*)$/ig) and (/^n(.*)$/ig) } @a;

总是 return 空列表,无论 @a 的值是什么。 @a 中的每个元素都会被考虑,但是其中 none 以 sn 开头——因为那是不可能的。

您想要的是测试 @a 中的字符串是否匹配 S N,如下所示:

grep { (/^s (.*)$/ig) or (/^n(.*)$/ig) } @a;

尽管如此,想要匹配多种可能性实际上是一个非常普遍的需求,因此有一个特殊的符号来表示。 "character class" 创建一个新原子,它匹配几种可能性中的任何一种。 .是字符class,自定义字符classes可以用尖括号创建,[].

因此:

grep { /^[sn]/i) } @a;

只匹配任何以 sn 开头的单词。以下代码将为您提供所需的输出:

my @arr = qw(sonata Samsung sony icic huawie nissan nokia);
my @filter = grep { /^[sn]/i } @arr;
print "@filter \n";

其中 ^[sn] 将匹配任何以 sn 开头的单词。

输出:

sonata Samsung sony nissan nokia