天天看點

perl 新得

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("*");

fkpic(/@files);

sub fkpic{

  my $files = shift;

  foreach my $file(@$files){

   if(-d $file){

     my $cwdir = cwd;

     chdir($cwdir . "/". $file);

     my @allfiles = glob("*");

     fkpic(/@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 [email protected] variable. If the eval caught a fatal error, [email protected] 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, [email protected] will be empty. Of course, that means that [email protected] 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: [email protected]" if [email protected];

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 ([email protected]) {

    print "An error occurred ([email protected]), 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 [email protected] (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 [email protected]

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*>

擷取目錄下檔案的簡便方法。