简体   繁体   English

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

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

How does the following grep function works (what does !/0o1Iil]/ do? ) 以下grep函数如何工作(什么做!/0o1Iil]/做什么?)

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

to produce the following in @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';

Here's the grep perldoc . 这是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 EXPR,LIST语法,这意味着任何Perl表达式都可以取代EXPR

grep takes the list provided to it, and returns only the items where EXPR is true. grep获取提供给它的列表,并仅返回EXPR为true的项目。

EXPR in this case is ! /0o1Iil]/ 在这种情况下EXPR是! /0o1Iil]/ ! /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. ! /0o1Iil]/ (为了便于添加而添加了空格),这意味着“此项目与正则表达式/0o1Iil]/ 匹配/0o1Iil]/ 。由于这些项目都没有与正则表达式匹配(它们都不包含字符串0o1Iil] )它们都是回来。

As other posters have mentioned, the regex was probably supposed to read /[0o1Iil]/ , which would remove characters that could be confused, eg 0 and o, 1 and I. This sounds useful for passwords or serial numbers, etc. 正如其他海报所提到的,正则表达式可能应该读取/[0o1Iil]/ ,这将删除可能混淆的字符,例如0和o,1和I.这对于密码或序列号等有用。

Btw, you could rewrite the grep into the clearer BLOCK form, and make the LIST construction explicit: 顺便说一句,你可以将grep重写为更清晰的BLOCK格式,并使LIST结构显式:

@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). !/[0o1Iil]/表示“与方括号中的任何字符都不匹配。”我认为你在第一个斜线后缺少一个开口方括号( [ ] - 意图是过滤掉所有可能的字符被误认为是其他的(0 / O,I / l / 1)。

The general syntax of a Perl grep is: Perl grep的一般语法是:

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. 它为LIST每个元素计算BLOCK ,并返回由表达式求值为true的元素组成的列表值。

In your case BLOCK is !/0o1Iil]/ which return true for those elements which do not contain the pattern 0o1Iil] . 在你的情况下, BLOCK!/0o1Iil]/ ,对于那些不包含模式0o1Iil]元素,它返回true。 Since in your case none of the LIST elements contain that pattern, the grep returns entire LIST . 因为在您的情况下没有LIST元素包含该模式,所以grep返回整个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 ai or al , then you would have got a LIST with all but these elements as the result. 如果BLOCK像: !/[0o1Iil]/对于那些不包含零,或小写o,或1,或I,或ai或al的元素返回true,那么你会得到一个LIST除了这些元素之外的所有元素。

The grep function acts as a filter on lists. grep函数充当列表上的过滤器。

In this case, the list is all alphanumeric characters. 在这种情况下,列表是所有字母数字字符。

The filter is specified by a regular expression. 过滤器由正则表达式指定。 The ! ! denotes not . 表示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. 正则表达式试图匹配任何出现的0o1Iil] (不是0o1Iil ,因为省略[在集合的开头会阻止正则表达式看到]作为字符类元字符。

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

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. 看到列表0..9, A..Z, a..z包含0o1Iil] ,没有要过滤的项目,这就是为什么你得到整个字母数字字符列表的原因。

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

Any items in the list matching 0 , o , 1 , I , i or l will be filtered out. 匹配0o1Iil的列表中的任何项目都将被过滤掉。 Thus, you'll get your alphanumeric list back, sans the above-mentioned six characters. 因此,你将得到你的字母数字列表,没有上面提到的六个字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM