开发者

How does Perl's grep function work with a regex?

How does the following grep function works (what does !/0o1Iil]/ do? )

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

to produce the following in @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';开发者_JAVA技巧
$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';


Here's the grep perldoc. The statement in your example is using the grep EXPR,LIST syntax, which means any Perl expression can take the place of EXPR.

grep takes the list provided to it, and returns only the items where EXPR is true.

EXPR in this case is ! /0o1Iil]/ (space added for readability) which means "this item is not matched by the regex /0o1Iil]/. Since none of those items are matched by that regular expression (none of them contain the string 0o1Iil]) they are all returned.

As other posters have mentioned, the regex was probably supposed to read /[0o1Iil]/, which would remove characters that could be confused, e.g. 0 and o, 1 and I. This sounds useful for passwords or serial numbers, etc.

Btw, you could rewrite the grep into the clearer BLOCK form, and make the LIST construction explicit:

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


// is a regular expression match operator. !/[0o1Iil]/ means “does not match any of the characters in the square brackets.” And I think you’re missing an opening square bracket ([) after the first slash – the intention is to filter out all characters that could be mistaken for some other (0/O, I/l/1).


The general syntax of a Perl grep is:

grep BLOCK LIST

It evaluates the BLOCK for each element of LIST and returns the list value consisting of those elements for which the expression evaluated to true.

In your case BLOCK is !/0o1Iil]/ which return true for those elements which do not contain the pattern 0o1Iil]. Since in your case none of the LIST elements contain that pattern, the grep returns entire LIST.

Had the BLOCK been like: !/[0o1Iil]/ which returns true for those elements which do not contain a zero, or a lowercase o, or a 1, or a I, or a i or a l, then you would have got a LIST with all but these elements as the result.


The grep function acts as a filter on lists.

In this case, the list is all alphanumeric characters.

The filter is specified by a regular expression. The ! denotes not. In other words, the resulting list should exclude whatever items match the regular expression.

The regular expression is trying to match any occurrence of 0o1Iil] (not 0o1Iil, because omitting a [ at the beginning of the set will prevent the regular expression from seeing the ] as the character class metacharacter.

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

Seeing that the list 0..9, A..Z, a..z contains no occurrence of 0o1Iil], there are no items to filter out, which is why you get your entire list of alphanumeric characters back.

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

Any items in the list matching 0, o, 1, I, i or l will be filtered out. Thus, you'll get your alphanumeric list back, sans the above-mentioned six characters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜