perl grep
转载:http://blog.sina.com.cn/s/blog_6072546301016g3f.html grep函数 (如果你是个Perl的新手,你可以先跳过下面的两段,直接到 Grep vs.loops 样例这一部分,放心,在后面你还会遇到它) <pre> grep BLOCK LIST grep EXPR,LIST </pre> grep 函数会用? LIST ?中的元素对? BLOCK ?或 EXPR 求值,而且会把局部变量 $_ 设置为当前所用的? ?中的元素。BLOCK 块是一个或多个由花括号分隔开的Perl 语句,而 List 则是一有序列表。EXPR 是一个或多个变量,操作符,字符,函数,子程序调用的组成的表达式。Grep 会对? ?块或? EXPR ?进行求值,将求值为%{color:red}真%的元素加入到 Grep 返回列表中。如果? ?块由多个语句组成,那么 Grep 以? ?中的最后一条语句的求值为准。LIST 可以是一个列表也可以是一个数组。在标量上下文中,grep 返回的是? ?或 EXPR 求值为真的元素个数。 请避免在?BLOCK?或 EXPR 块中修改 $_,因为这会相应的修改?LIST?中元素的值。同时还要避免把 grep 返回的列表做为左值使用,因为这也会修改?LIST?中的元素。(所谓左值变量就是一个在赋值表达式左边的变量)。一些 Perl hackers 可能会利用这个所谓的”特性”,但是我建议你不要使用这种混乱的编程风格. grep 与循环 这个例子打印出 myfile 这个文件中含有 terriosm 和 nuclear 的行(大小写不敏感). open FILE "<myfile" or die "Can't open myfile: $!"; print grep /terrorism|nuclear/i,<FILE>; 对于文件很大的情况,这段代码耗费很多内存。因为 grep 把它的第二个参数作为一个列表上下文看待,所以 < > 操作符返回的是整个的文件。更有效的代码应该这样写: while ($line = <FILE>) { if ($line =~ /terrorism|nuclear/i) { print $line } } 通 过上面可以看到,使用循环可以完成所有 grep 可以完成的工作。那为什么我们还要使用 grep 呢?一个直观的答案是 grep 的风格更像 Perl,而 loops(循环)则是 C 的风格。一个更好的答案是,首先,grep 很直观的告诉读者正在进行的操作是从一串值中选出想要的。其次,grep 比循环简洁。(用 软件 工程的说法就是 grep 比循环更具有内聚力)。基本上,如果你对 Perl 不是很熟悉,随便你使用循环。否则,你应该多使用像 grep 这样的强大工具. 计算数组中匹配给定模式的元素个数 在一个标量上下文中,grep 返回的是匹配的元素个数. $num_apple = grep /^apple$/i,@fruits; ^ 和 $ 匹配符的联合使用指定了只匹配那些以 apple 开头且同时以 apple 结尾的元素。这里 grep 匹配 apple 但是 pineapple 就不匹配。 输出列表中的不同元素 @unique = grep { ++$count{$_} < 2 }? qw(a b a c d d e f g f h h); print "@uniquen"; 输出结果: a b c d e f g h $count{$_}
?是 Perl 散列中的一个元素,是一个键值对 ( Perl中的散列和计算机科学中的哈希表有关系,但不完全相同) 这里 count 散列的键就是输入列表中的各个值,而各键对应的值就是该键是否使?
?估值为真的次数。当一个值第一次出现的时候?
?的值被估为真(因为小于2),当该值再次出现的时候就会被估计为假(因为等于或大于2)。
取出列表中出现两次的值 @crops = qw(wheat corn barley rice corn soybean hay? alfalfa rice hay beets corn hay); @duplicates = grep { $count{$_} == 2 }? grep { ++$count{$_} > 1 } @crops; print "@duplicatesn"; 在 grep 的第一个列表元素被传给? ?或 EXPR 块前,第二个参数被当作列表上下文看待。这意味着,第二个 grep 将在左边的 grep 开始对? ?进行估值之前完全读入 count 散列。 列出当前目录中的文本文件 @files = grep { -f and -T } glob '* .*'; print "@filesn"; glob 函数是独立于操作系统的,它像 Unix 的 shell 一样对文件的扩展名进行匹配。单个的? *
?表示匹配所以当前目录下不以?
.
?开头的文件,?
.*
?表示匹配当前目录下以?
<p ?
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |