Perl的grep函数如何与正则表达式一起工作?

时间:2010-03-20 16:51:58

标签: regex perl grep

以下grep函数如何工作(!/0o1Iil]/做什么?)

@chars = grep !/0o1Iil]/, 0..9, "A".."Z", "a".."z"; 
use Data::Dumper; 
print Dumper @chars;

在@chars中生成以下内容?

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;
$VAR5 = 4;
$VAR6 = 5;
$VAR7 = 6;
$VAR8 = 7;
$VAR9 = 8;
$VAR10 = 9;
$VAR11 = 'A';
$VAR12 = 'B';
$VAR13 = 'C';
$VAR14 = 'D';
$VAR15 = 'E';
$VAR16 = 'F';
$VAR17 = 'G';
$VAR18 = 'H';
$VAR19 = 'I';
$VAR20 = 'J';
$VAR21 = 'K';
$VAR22 = 'L';
$VAR23 = 'M';
$VAR24 = 'N';
$VAR25 = 'O';
$VAR26 = 'P';
$VAR27 = 'Q';
$VAR28 = 'R';
$VAR29 = 'S';
$VAR30 = 'T';
$VAR31 = 'U';
$VAR32 = 'V';
$VAR33 = 'W';
$VAR34 = 'X';
$VAR35 = 'Y';
$VAR36 = 'Z';
$VAR37 = 'a';
$VAR38 = 'b';
$VAR39 = 'c';
$VAR40 = 'd';
$VAR41 = 'e';
$VAR42 = 'f';
$VAR43 = 'g';
$VAR44 = 'h';
$VAR45 = 'i';
$VAR46 = 'j';
$VAR47 = 'k';
$VAR48 = 'l';
$VAR49 = 'm';
$VAR50 = 'n';
$VAR51 = 'o';
$VAR52 = 'p';
$VAR53 = 'q';
$VAR54 = 'r';
$VAR55 = 's';
$VAR56 = 't';
$VAR57 = 'u';
$VAR58 = 'v';
$VAR59 = 'w';
 $VAR60 = 'x';
 $VAR61 = 'y';
 $VAR62 = 'z';

4 个答案:

答案 0 :(得分:6)

这是grep perldoc。您的示例中的语句使用grep EXPR,LIST语法,这意味着任何Perl表达式都可以取代EXPR

grep获取提供给它的列表,并仅返回EXPR为true的项目。

在这种情况下,EXPR为! /0o1Iil]/(为了便于阅读而添加了空格),这意味着“此项目与正则表达式/0o1Iil]/匹配。因为这些项目都不匹配通过该正则表达式(它们都不包含字符串0o1Iil]),它们都被返回。

正如其他海报所提到的那样,正则表达式可能应该是/[0o1Iil]/,这会删除可能混淆的字符,例如0和o,1和I.这对密码或序列号等非常有用。

顺便说一句,您可以将grep重写为更清晰的BLOCK格式,并使LIST结构明确:

@chars = grep { ! /[0o1Iil]/ } (0..9, 'A'..'Z', 'a'..'z');

答案 1 :(得分:2)

//是正则表达式匹配运算符。 !/[0o1Iil]/表示“与方括号中的任何字符都不匹配。”而且我认为你在第一个斜线后缺少一个空方括号([) - 意图是过滤掉所有可能被误认为是其他人的字符(0 / O,I / l / 1)。

答案 2 :(得分:1)

Perl grep的一般语法是:

grep BLOCK LIST

它评估BLOCK的每个元素的LIST,并返回由表达式求值为true的元素组成的列表值。

在您的情况下,BLOCK!/0o1Iil]/,对于那些不包含模式0o1Iil]的元素,它们返回true。由于在您的情况下,LIST元素都不包含该模式,因此grep将返回整个LIST

如果BLOCK类似于:!/[0o1Iil]/,对于那些 不包含零,或小写o,或1或I的元素,它返回true或ai或al ,那么除了这些元素之外,您将获得LIST作为结果。

答案 3 :(得分:0)

grep函数充当列表上的过滤器。

在这种情况下,列表是所有字母数字字符。

过滤器由正则表达式指定。 !表示not。换句话说,结果列表应该排除与正则表达式匹配的任何项目。

正则表达式尝试匹配任何0o1Iil](不是0o1Iil,因为在集合的开头省略[会阻止正则表达式看到{{ 1}}作为字符类元字符。

](没有grep {not /0o1Iil]/} 0..9, A..Z, a..z):

看到列表[不包含0..9, A..Z, a..z,因此没有可过滤的项目,这就是为什么要将整个字母数字字符列表恢复原状。

0o1Iil](使用grep {not /[0o1Iil]/} 0..9, A..Z, a..z):

匹配[0o1Ii的列表中的所有项目都将被过滤掉。因此,你将得到你的字母数字列表,没有上面提到的六个字符。