1. "@"当作数组缘于array首字母哦,标量呢?"$"当然是scalar了。
2. "=>"是comma(,)的同义词哦,所以不要以为"=>"只用于hash!
@array = (1,2=>3=>4=>5);
print "@array"#amazing,output:1 2 3 4 5
3. 要输出一个数组,那么如何分隔开数组元素呢?
print join("/n",@array);#老土!
print "@array";#默认元素之间为空格,如果想用其他分隔符,修改$"(刀了和一个双引号);
4 可以象打开文件一样地打开管道。
open (SESAME,"| output-pipe-command");
open (SESAME,"input-pipe-command | ");
5. 指数操作符"**",比如2**4=16,哈哈,当然你可以打一连串*,不知道是什么玩意了。
6. repeat operator "x",比较好玩
print "12"x 3;# out:121212
print "-" x $screenwidth;
print "/a"x 100000;#bt,你的电脑费了!
7. open (IN,"-");#猜猜是什么,竟然是标准输入,标准输出是什么?plz tell me if u know.
8. 来几个变态的赋值操作
$kissyou x=1000;#omg! kiss you a thousand time.
$begger ||= "100 dollar";#if the $begger have nothing(undefined),then give her $100 if I have.(But I have nothing too!Q)
9. 先增还是后增? 如果$i++和++$i对你一样,那么后者(pre-increment)效率高些。why? this is not clear to me .酱紫!
10.如何去的文件信息?用stat函数啊!
$file_size = (stat(filehandle or filename))[7];#第8项为字节数。注意:stat函数外层要加括号,告诉人家他是list context,ok?
11. 来个自己写的递归查找文件
use Cwd;
use strict;
use File::Copy;
mkdir("c:/temp/");
my $trg="c:/temp/";
my $dir = cwd;
my @files = glob("*");
ftpic(/@files);
sub ftpic{
my $files = shift;
foreach my $file(@$files){
if(-d $file){
my $cwdir = cwd;
chdir($cwdir . "/". $file);
my @allfiles = glob("*");
ftpic(/@allfiles);
chdir($cwdir);
}
if(-f $file){
if($file =~ /.*?jpg/ and (stat($file))[7] > 30000)#把大于30k的jpg文件移到目标文件夹
{copy ($file,$trg);}
}
}
}
12.what is truth? Perl 判官如何分别对错?
四条法律:
(1)Any string is true except for "" and "0";
(2)Any number is true exceppt for 0.
(3)Any reference is true.
(4)Any undefined value is false.
Make a test:
<1> 10-10 #false because 10-10 is 0
<2> 0.00 #false because 0.00 became 0
<3> "0.00" #true! ft! haha, because "0.00" is not empty neither "0"
<4>"0.00" + 0#false! puke! ceforced by the "+" ,it becames 0;
<5>/$a #true! even if $a is flase.
<6>undef() #false!a function return a underfined value ,so it is false.
13. foreach 中的循环变量是元素的reference 而不是copy,所以,对它进行改动,其实就是对所循环的list作了改动。
14. 正则匹配中的left-most原则高于longest原则!
$ = "fred xxxxx jelinek";
s/x*//;#so what will be $_? in fact it will not change! because left-most RE match "" before "fred";
15. Geedy 匹配 and non-greedy .这个简单,默认的是greedy,但是我们加上一个"?"就变成最小匹配了。
$_ = "hfjiang xxx mtlabmtlabmtlab";
s/^hfjiang.*mtlab/sound/;#$_="sound";
s/^hfjiang.*?mtlab/sound/;#$_="soundmtlabmtlab";
16. backreference 的用法。
#在同一个模式里面的backreference 用/1,/2等。
m/<(.*?)>(.*?)<///1>/;#匹配如<B>Bold</B> 这样的标签
#模式外面的用$1,$2等。注意s///的两个模式之间也算模式外面。
s/(/w+)/s+(/w+)/$2 $1/;#调换两个词的位置
注意
/1 和$1 ,/1.../9默认都是匹配,但是/10,/11要看情况,/i(i>=10)表示如果最近的成功的匹配中有第i个匹配,否则。。。。
17. $' $` $& $+ 在匹配中都是很有用的。
$+ returns whatever the last braket matched.
$& returns the entire matched string.
$` returns everything before the matched string.
$' returns everything after the matched string.
##########################
#example
$_ = "xxxxabbbcczzzz";
m/(a((b+)(c+)))/g;
print <<EOP
/$1 = $1
/$2 = $2
/$3 = $3
/$4 = $4
/$+ = $+
/$& = $&
/$` = $`
/$/' = $'
EOP
;
#########################
output:
$1 = abbbcc
$2 = bbbcc
$3 = bbb
$4 = cc
$+ = cc
$& = abbbcc
$` = xxxx
$' = zzzz
##########################
我们可以总结出几点通过这个例子。
(1)$1,$2..的顺序是从左括号从左到右数起,到对应的右括号为止;
(2)几个特殊变量会挺有用的,真的!不信在下面将给你演示一个$`的例子。
(3)上面例子中输出时用了"here document"格式,帅吧?后面给你讲。
18. split模式中括号的用法.
(1)如果在返回的list中不想要分隔符,那么在分隔模式中不加括号。
(2)如果在返回的list中想要分隔符,那么在分隔模式中加括号。
尝试下面例子的两种情况
#######################################################################
#example
@arr = split /[-,]/, "1-10,20"; # or @arr = split /([-,])/, "1-10,20";
$" = "/n";
print "@arr";
########################################################################
那么有个问题:如果必须用括号,但是还不想要分隔符,咋办?凉拌!下面在RE extension中给您分解!
19.RE extension的用法
RE ext 的语法呢很简单,就是括号里面第一个字符是个问号(?xxx),这东东在早先的版本里面会被认为是语法错误,现在的作用可
大着哩,而且还在不断扩充哦(I think)!目前支持的语法有几个。
(1) (?#text) 这玩艺个人觉得还不如在RE的pattern中用/x开关,直接用"#"加注释的好。
(2)(?:...) 这个好玩,可以用来解决split中必须用括号但不想要分隔符的问题。
#example
$_ = "xxxx a yyyy b zzzz c mmmm";
split (//b(a|b|c)/b/);#得到("xxxx", "a", "yyyy", "b", "zzzz", "c", "mmmm")
split (//b(?:a|b|c)/b/);#得到("xxxx", "yyyy","zzzz", "mmmm")
(3)(?=...)和(?!...)这两兄弟叫做是lookhead assertion,往前探脑袋瞧一瞧但并不吃进来。
m/girl(?=boy)/;#看一下"girl"后面是不是跟着一个boy.
m/girl(?!boy)/;#看一下"girl"后面是不是没跟着一个boy.
那么,有同学说了,想看看前面是不是没有boy护卫,怎么看?
这样吗?
m/(?!boy)girl/#Wrong,这设备只能往后看,看不到girl前面的情况,
别急,有办法搞掂!用我们的$`,他就像是个潜望镜,可以看到前面的情况。
if(/girl/ and $`!~/boy$/) #道路虽然曲折,但是还是把女孩子的护卫情况搞清楚了。:D
20. here document 的用法注意
(1)以行为操作单位,所以结束符要单起一行,而且后面不能跟";"。
(2)标记要紧挨着"<<"
####################################################################################
print <<EOP;#print <<"EOP" 两者一样,下面的段落可以进行内插。但是print <<'EOP'不进行内插
xxxxxxxxxxxxxx
xxxxxxxxxxx
EOP
print << x 10;#以空行为结束符,输出下面句子十次。更直观的写法:print <<"" x 10;
Day Day up!
###########################################################################
(3)ft!还可以进行一些变态操作:调用系统或者运算。
print <<`EOC`;
dir
EOC
print <<ADD
123
ABC
+321;#print 444.
21. 多行匹配/m,采用learning perl 中的例子。
Matching Multiple-line Text
Classic regular expressions were used to match just single lines of text. But since Perl can work with strings of any length, Perl's patterns can match multiple lines of text as easily as single lines. Of course, you have to include an expression that holds more than one line of text. Here's a string that's four lines long:
$_ = "I'm much better/nthan Barney is/nat bowling,/nWilma./n";
Now, the anchors ^ and $ are normally anchors for the start and end of the whole string (see Section 8.3 in Chapter 8). But the /m regular expression option lets them match at internal newlines as well (think m for multiple lines). This makes them anchors for the start and end of each line, rather than the whole string. So this pattern can match:
print "Found 'wilma' at start of line/n" if /^wilma/b/im;
Similarly, you could do a substitution on each line in a multiline string. Here, we read an entire file into one variable,[9] then add the file's name as a prefix at the start of each line:
[9] Hope it's a small one. The file, that is, not the variable.
open FILE, $filename
or die "Can't open '$filename': $!";
my $lines = join '', <FILE>;
$lines =~ s/^/$filename: /gm;
22. trapping errors with eval
Sometimes, your ordinary, everyday code can cause a fatal error in your program. Each of these typical statements could crash a program:
$barney = $fred / $dino; # divide-by-zero error?
print "match/n" if /^($wilma)/; # illegal regular expression error?
open CAVEMAN, $fred # user-generated error from die?
or die "Can't open file '$fred' for input: $!";
You could go to some trouble to catch some of these, but it's hard to get them all. (How could you check the string $wilma from that example to ensure that it makes a valid regular expression?) Fortunately, Perl provides a simple way to catch fatal errors: wrap the code in an eval block:
eval { $barney = $fred / $dino } ;
Now, even if $dino is zero, that line won't crash the program. The eval is actually an expression (not a control structure, like while or foreach) so that semicolon is required at the end of the block.
When a normally fatal error happens during the execution of an eval block, the block is done running, but the program doesn't crash. So that means that right after an eval finishes, you'll be wanting to know whether it exited normally or whether it caught a fatal error for you. The answer is in the special $@ variable. If the eval caught a fatal error, $@ will hold what would have been the program's dying words, perhaps something like: Illegal division by zero at my_program line 12. If there was no error, $@ will be empty. Of course, that means that $@ is a useful Boolean (true/false) value, true if there was an error, so you'll sometimes see code like this after an eval block:
print "An error occurred: $@" if $@;
The eval block is a true block, so it makes a new scope for lexical (my) variables. This piece of a program shows an eval block hard at work:
foreach my $person (qw/ fred wilma betty barney dino pebbles /) {
eval {
open FILE, "<$person"
or die "Can't open file '$person': $!";
my($total, $count);
while (<FILE>) {
$total += $_;
$count++;
}
my $average = $total/$count;
print "Average for file $person was $average/n";
&do_something($person, $average);
};
if ($@) {
print "An error occurred ($@), continuing/n";
}
}
How many possible fatal errors are being trapped here? If there is an error in opening the file, that error is trapped. Calculating the average may divide by zero, so that error is trapped. Even the call to the mysteriously named &do_something subroutine will be protected against fatal errors, because an eval block traps any otherwise-fatal errors that occur during the time that it's active. (This feature is handy if you have to call a subroutine written by someone else, and you don't know whether they've coded defensively enough to avoid crashing your program.)
If an error occurs during the processing of one of the files, we'll get an error message, but the program will go on to the next file without further complaint.
You can nest eval blocks inside other eval blocks. The inner one traps errors while it runs, keeping them from reaching the outer blocks. (Of course, after the inner eval finishes, if it caught an error, you may wish to re-post the error by using die, thereby letting the outer eval catch it.) An eval block traps any errors that occur during its execution, including errors that happen during subroutine calls (as we saw in the example earlier).
We mentioned earlier that the eval is an expression, which is why the trailing semicolon is needed after the closing curly brace. But since it's an expression, it has a return value. If there's no error, it's like a subroutine: the return value is the last expression evaluated, or it's returned early with an optional return keyword. Here's another way to do the math without having to worry about divide-by-zero:
my $barney = eval { $fred / $dino };
If the eval traps a fatal error, the return value is either undef or an empty list, depending upon the context. So in the previous example, $barney is either the correct result from dividing, or it's undef; we don't really need to check $@ (although it's probably a good idea to check defined($barney) before we use it further).
There are four kinds of problems that eval can't trap. The first group are the very serious errors that crash Perl itself, such as running out of memory or getting an untrapped signal. Since Perl itself isn't running, there's no way it can trap these errors.[2]
[2] Some of these errors are listed with an (X) code on the perldiag manpage, if you're curious.
Of course, syntax errors inside the eval block are caught at compile time—they're never returned in $@.
The exit operator terminates the program at once, even if it's called from a subroutine inside an eval block. (This correctly implies that when writing a subroutine, you should use die rather than exit to signal when something goes wrong.)
The fourth and final kind of problem that an eval block can't trap are warnings, either user-generated ones (from warn) or Perl's internally generated warnings (requested with the -w command-line option or the use warnings pragma). There's a separate mechanism from eval for trapping warnings; see the discussion of the __WARN__ pseudosignal in the Perl documentation for the details.
We should also mention that there's another form of eval that can be dangerous if it's mishandled. In fact, you'll sometimes run across someone who will say that you shouldn't use eval in your code for security reasons. They're (mostly) right that eval should be used only with great care, but they're talking about the other form of eval, sometimes called "eval of a string". If the keyword eval is followed directly by a block of code in curly braces, as we're doing here, there's no need to worry—that's the safe kind of eval.
23. map grep 也采用learning perl 中的例子。
##Picking Items from a List with grep
Sometimes you'll want only certain items from a list. Maybe it's only the odd numbers selected from a list of numbers, or maybe it's only the lines mentioning Fred from a file of text. As we'll see in this section, picking some items from a list can be done simply with the grep operator.
Let's try that first one and get the odd numbers from a large list of numbers. We don't need anything new to do that:
my @odd_numbers;
foreach (1..1000) {
push @odd_numbers, $_ if $_ % 2;
}
That code uses the modulus operator (%), which we saw in Chapter 2. If a number is even, that number "mod two" gives zero, which is false. But an odd number will give one; since that's true, only the odd numbers will be pushed onto the array.
Now, there's nothing wrong with that code as it stands—except that it's a little longer to write and slower to run than it might be, since Perl provides the grep operator:
my @odd_numbers = grep { $_ % 2 } 1..1000;
That line gets a list of 500 odd numbers in one quick line of code. How does it work? The first argument to grep is a block that uses $_ as a placeholder for each item in the list, and returns a Boolean (true/false) value. The remaining arguments are the list of items to search through. The grep operator will evaluate the expression once for each item in the list, much as our original foreach loop did. For the ones where the last expression of the block returns a true value, that element is included in the list that results from grep.
While the grep is running, $_ is aliased to one element of the list after another. We've seen this behavior before, in the foreach loop. It's generally a bad idea to modify $_ inside the grep expression, because this will damage the original data.
The grep operator shares its name with a classic Unix utility that picks matching lines from a file by using regular expressions. We can do that with Perl's grep, which is much more powerful. Here we pull only the lines mentioning fred from a file:
my @matching_lines = grep { //bfred/b/i } <FILE>;
There's a simpler syntax for grep, too. If all you need for the selector is a simple expression (rather than a whole block), you can just use that expression, followed by a comma, in place of the block. Here's the simpler way to write that latest example:
my @matching_lines = grep //bfred/b/i, <FILE>;
##Transforming Items from a List with map
Another common task is transforming items from a list. For example, suppose you have a list of numbers that should be formatted as "money numbers" for output, as with the subroutine &big_money (from Chapter 15). But we don't want to modify the original data; we need a modified copy of the list just for output. Here's one way to do that:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data;
foreach (@data) {
push @formatted_data, &big_money($_);
}
That looks similar in form to the example code used at the beginning of the section on grep, doesn't it? So it may not surprise you that the replacement code resembles the first grep example:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data = map { &big_money($_) } @data;
The map operator looks much like grep because it has the same kind of arguments: a block that uses $_, and a list of items to process. And it operates in a similar way, evaluating the block once for each item in the list, with $_ aliased to a different original list element each time. But the last expression of the block is used differently; instead of giving a Boolean value, the final value actually becomes part of the resulting list.[3]
[3] One other important difference is that the expression used by map is evaluated in a list context and may return any number of items, not necessarily one each time.
Any grep or map statement could be rewritten as a foreach loop pushing items onto a temporary array. But the shorter way is typically more efficient and more convenient. Since the result of map or grep is a list, it can be passed directly to another function. Here we can print that list of formatted "money numbers" as an indented list under a heading:
print "The money numbers are:/n",
map { sprintf("%25s/n", $_) } @formatted_data;
Of course, we could have done that processing all at once, without even the temporary array @formatted_data:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
print "The money numbers are:/n",
map { sprintf("%25s/n", &big_money($_) ) } @data;
As we saw with grep, there's also a simpler syntax for map. If all you need for the selector is a simple expression (rather than a whole block), you can just use that expression, followed by a comma, in place of the block:
print "Some powers of two are:/n",
map "/t" . ( 2 ** $_ ) . "/n", 0..15;
24. 数组下标,$#array=-1 when @array undef. 数组扩充与缩减。
多位数组的实现以及插入行列,以及遍历时看作reference 来访问。
参见Programming Perl 2ed version
或者Perllol
25. 数字注意事项
prefix = "0x"表示16进制
prefix = "0"表示8进制
大数据用下划线"12_3_4___5",多几个也没事。
26. q{}的妙用
$chunck_of_code = q{
if($condition){
print "hulala";
}
}
27. glob file operator <wantfile> <*> <asa*>
获取目录下文件的简便方法。