Perl学习笔记

Perl 的理念:There is more than one way to do it!

一,简介

1,Perl的敘述句是用分号(;)隔开的
2,Perl是以井字号(#)作为代码的註解标示,也就是只要以井字号开始,到敘述句結束前的內容都会被当成注解

二,变量 $

1,Perl的单引号中,是无法使用像/n(换行字元),/t(跳格字元)这些特殊字元的(不会被解释)

  Perl的双引号中,能解释这些字符:

  例如: $c = "在/tPerl/t中使用字串非常容易";

      $d = '在/tPerl/t中使用字串非常容易';

      print "$c/n";   # 在      Perl    中使用字串非常容易

      print "$d/n";   # 在/tPerl/t中使用字串非常容易

2,连接两个字串,用符号 “ . ”,将两个字串相加用“ + ”

  #!/usr/local/bin/perl

    $a = "number";
    $b = 3674;
    $c = "4358";
    $d = $a.$b;
    $e = $b+$c;
    $m = "string"

    print "$d/n";  #number3674
    print "$e/n";  #8032
  
    print  $a.$m;  #numberstring
    print  $a+$m;  #0

3,如果在定义一个变量没有给定初始值时,则会被认为 undef. 函数defined($name)

4,<STDIN>:
   my $num = <STDIN>;
   chomp($num);

三,阵列 @

1,Perl 的阵列结构:例如你可以定义一个变量名叫做 @array。然后利用 $array[0],$array[1]...的方式存取阵列里的元素

定义方式: 

   1)
   my @array;
   $array[0] = 'first';
   $array[1] = 'second';
   $array[2] = 'third';
  
   2)
   my ($array[0], $array[1], $array[2]) = qw/first second third..../;

   3)
   my @array = qw/first second third/;

   4)
   my @array = qw{first second third};

  

2,$#array  取得阵列的最后一个索引值(这里指的是索引值,而不是阵列的最后一个元素的值,一般都为数字,比如0,1,2,...)

  $array  #输出的是阵列的长度。

  所以我们可以利用($#array + 1)得到目前陣列中的元素個數,其实就等于$array

  ($#array + 1) = $array

3,push, pop:从阵列的后面(尾)对阵列进行运算

   my @array = qw{first second third};
   my @array2 = qw/fourth fifth/;
   push @array, @array2;
   print @array;

   输出为:firstsecondthirdfouthfifth

4,shift/unshift:从阵列的前面(头)对阵列进行运算

   my @array = (1...10);
   shift @array;    # 我把1拿掉了
   unshift @array, 0;   # 現在補上0
   print @array;    # 現在陣列的值變成了(0, 2...10)
   
   Next:
   my @array = (1...10);    # 我們還是使用這個陣列
   shift @array;     # 我把1拿掉了
   print "$_/t$array[$_]/n" for (0...9);  # 現在陣列的值變成了(0, 2...10)
 
   0 2, 1 3, 2 4, 8 10, 9

 ** 需要注意上面代码中最后一句print "$_/t$array[$_]/n" for (0...9); $_表示的是for循环里的每一个值。

5,生鱼切片:
    my @array = (0...10);
    my @array2 = @array[2...4];
    print @array2;    # 沒錯,你拿到了(2, 3, 4) 三個元素

    以上用法称之为切片儿 大笑 

6,sort:排序
  
    my @array = qw/45 33 75 21 38 69 46/;
    @array = sort { $a <=> $b } @array;
  
    這樣Perl就會幫我們把陣列重新排列成為
    21      33      38      45      46      69      75

    其實,如果你這樣寫也是有相同的效果:

    @array = sort @array;

    當然,如果你需要比較複雜的排序方式,就要把包含排序的區塊加入,所以你也可以寫 :

    @array = sort { $b <=> $a } @array;
 
    其中$a跟$b是Perl的預設變數,在排序時被拿來作為兩兩取出的兩個數字。而<=>則是表示數字的比較,如果陣列中的元素是字串,則必須以cmp來進行排序。


    复杂一些还可以这样写:
    @array = sort { ($a**2) <=> ($b**2) } @array; # 這次我們以平方進行排序

7,join split

    把串列裡面的元素值用某種方式連接成一個字串:
    print join ',',  qw/-4 45 -33 8 75 21 -15 38 -69 46/;

8,map:

    所謂map就是把陣串列裡的元素一一提出,並進行運算,然後得到另外一個串列,我們就把所得到的串列放到陣列中.

  my @array = map { sqrt($_)*10 } qw/45 33 8 75 21 15 38 69 46/; #开平方乘以10

  67.0820393249937
    57.4456264653803
    28.2842712474619
    86.6025403784439
    45.8257569495584
    38.7298334620742
    61.6441400296898
    83.0662386291807
    67.8232998312527

9,grep: 對串列進行篩選

   my @array = qw/6 -4 8 12 -22 19 -8 42/;   # 指定一個串列給陣列 @array
    my @positive = grep {$_ > 0} @array;   # 把@array裡大於零的數字取出
    print "$_/n" for @positive;      # 印出新的陣列 @positive

四,控制结构:

1,区块{}跟变量的应用:
   my $a = 3;
   my $b = 9;
  {
    print "$a/n";  # 屬於外層的區塊,所以你會看到 3
    my $b = 6;     # 定義了這區塊內自己的變數
    print "$b/n";  # 於是你看到的這個$b的值其實是6
  }
  {
    print "$a/n";  # 這個區塊沒有自己的$a
    print "$b/n";  # 也沒有自己的$b
            # 所以你在這裡看到的值其實是上一層的變數值
   }
    print "$a/n";      # 這裡似乎毫無疑問
    print "$b/n";     # Perl還是印出期待中的3跟9

2,if 跟 unless

  if (!($a < 3))  等于 unless ($a <3)

3, 一行的判斷

    if ($num < 5) {
       $num++;
    }
    等于这一句: $num++ if ($num < 5);

    while (1) {               # 在這裡,程式會得到永遠的真值
    print "這是無限迴圈";
    }
    等于这一句:print "這是無限迴圈" while (1);

4,呵呵,经典的计算阶乘的例子:
    my $num = 1;
    my $result = 1;       # 小心,這裡一定要指定$result為1
    while ($num <= 10) {   # 確定你是否超過範圍
      $result*=$num;
      $num = $num + 1;
    }

    另一种写法:
    my $result = 1;
    for (my $num = 1; $num <= 10; $num = $num + 1) {
       $result *= $num;
    }


5,Perl的神奇写法:
   
    for my $num (1...10) {   # 這就是表示$num從1到10
        print $num;
    }

    這其實可以寫成:

    for (1...10) {           # $_ 經常被拿來作為迴圈的預設變數
       print $_;
    }

    更簡化的寫法:

    print for (1...10);

6,foreach 函数:

  my @array = qw/1 2 3 4 5/;

  for (my $i = 0; $i < $#array; $i++) {
       print $array[$i];
   }
   等同于: print foreach (@array);  foreach my $element (@array);

7,my @array = qw/6 -4 8 12 -22 19 -8 42/;
    my @positive;
    for (@array) {      # 針對陣列的每個元素檢察
      push @positive, ($_**2) if ($_ > 0);  # 如果大於零就取平方值
    }

    print for (@positive);
   
    等同于:
    my @array = qw/6 -4 8 12 -22 19 -8 42/;
    my @positive = map { $_**2 } grep { $_  > 0 } @array;
                 
    # 倒裝,把@array的元素先放進 grep 檢查,再把通過檢查的結果利用map取得平方值放 進新的陣列

五, Hash  %

1, Hash % 赋值:
    1) my %hash = qw/1 one 2 two 3 three/;
    2) my %hash = (1, 2, 3, 4, 5);
    3) my %hash = (
            1 => 'one',
            2 => 'two',
            3 => 'three',
            );
   

2, each 函数:

   每次each函數都会返回一个包含两个元素的阵列,其中这两个值分别是一个HASH的键值跟Value。

   my %hash = (
            '168.1.2.1' => 'verdi',
            '192.1.2.2' => 'wagner',
            '168.1.2.3' => 'beethoven',
            );      # 定義主機跟ip 的對應
   my @hostname;
   while (my ($key, $value) = each (%hash)) {
   if ($key =~ /^192/) {    # 要找出ip以192開頭的部份
        push @hostname, $value;    # 找到之後放入新的陣列中
   }
   }

   print @hostname;

3,Hash的Key函数Value函数的用法:

   把key或者value放到同一个阵列中:
   my @keys = keys(%hash); my @values = values(%hash);

4,exists

  print "exist" if (grep { $_ eq 'video' } keys (%hash));

  等于: print "exists" if (exists $hash{video});

5,delete

   delete $hash{video}; 将hash表中的一对值删除,包括键值跟value.并不是undef的概念.

六, 子函数 &

(有些地方叫做副常式,个人认为就是个子函数)

1, 表现方式,调用时可以加&,也可以不加, 且可以放到代码的任何地方.例如:

   my $num = 12;
   print hex($num),"/n";   # 這是Perl提供的hex函式
   print &hex($num),"/n";   # 我們自己寫的hex副常式

   sub hex {
       my $param = shift;
       $num*2;
   }

2,参数的使用:

  &hello("world");   # 傳參數"world"

  sub hello {
      my $name = shift @_;  # 把參數從預設陣列拿出來
      print "hello $name/n";  # 根據參數不同印出不同的招呼
  }

3,返回值,return

    my $return = &adv(4, 2, 6, 4, 9);  # 我們一次傳入五個參數
    print $return;

    sub adv {
       my $total;
       for (@_) {   # 針對預設陣列進行運算
          $total += $_; # 加總
       }
       $total/($#_+1);   # 除以總數 (取平均)
     }

4, 比较local与my的不同用法:(看例子意会吧,不做解释了)

  $var1 = "global";
  $var2 = "for local";
  &sub1;      # var1=local var2=for local
  &sub2;      # var1=golbal var2=for local

  sub sub1 {
      local $var1 = "local";
      my $var2 = "my";
      &sub2;
  }

  sub sub2 {
      print "var1=$var1/tvar2=$var2/n";
  }

七, 深入控制结构

1,last: 最后

  for (1...10) {
      last if ($_ == 8);
      print;     # 這樣會印出  1...7
    }

2,redo

  for (1...10) {
      $_++;     # redo 其實會來這裡
      redo if ($_ == 8);    # 我們希望 redo 的條件
      print;          # 會印出 2, 3, 4, 5, 6, 7, 9, 9, 10, 11
    }

  这时需要注意for (1...10)的用法,它就相当于for (my @array = (1...10))

  for ($_ = 1; $_ <= 10; $_++) {
      $_++;     # 我們還是先把得到的元素進行累加
      redo if ($_ == 8);    # 遇到8的時候就重複一次
      print $_;        # 印出目前的 $_,我們得到2, 4, 6, 9, 11
    }

  redo 会去重复循环内部的命令

3,next

  for (1...10) {
      next if ($_%2);   # 以串列值除以2的餘數判断,余数为0时,也就是偶数时,IF条件为假.余数为1时,IF条件为真,执行下面的命令。
      print $_;

  }

4,标识

  LABEL: for my $outter (1...5) {
      for (1...10) {
         if ($_ > 2) { next LABEL; } else { print "inner $_ /n"; }
      }
    next LABEL if ($outter%2);
    print $_;
   }

5,switch
  
   if (..){ $case=1; }
   if (..){ $case=2; }
   if (..){ $case=3; }

   switch:{
      if ($case=1){...}
      if ($case=2){...}
      if ($case=3){...}
   }

6, 三元运算符
  
   my ($a, $b) = (42, 22);
   my $max = ($a > $b) ? $a : $b;
   print "$max/n";

7, || 运算符

   sub input {
     my $key = shift || "預設值";
     print "$key/n";
   }

 

八,正则表达式基本性质 =~

    m//, //,m{}, m||, m!!

   1)比对单一的字符串
   my $answer = "monger";
   until ((my $patten = <STDIN>) =~ /$answer/) {   
          # 持續進行,直到使用者輸入含有 monger 的字串
   print "wrong/n";      # 在這裡,表示比對失敗
   };

   2) * 可以比对0到任何次, 也就是匹配的概念
   my $answer = "mo*r";     # 使用量詞
   while (1) {        # 所以其實是無限迴圈
     if ((my $patten = <STDIN>) =~ /$answer/) {  # 判斷是否比對成功
        print "*match*/n";
     } else {
        print "*not match*/n";
     }
   };

   3) + 可以匹配1到任何,不能匹配0次,比如"mr"是不能比对出来的.
   my $answer = "mo+r";

   4) {min, max} 可限制比对的次数
   my $answer = "mo{2,4}r";
  
   当然还可以省略掉其中的一个限制,比如{min,}{3,},表示3次或3次以上
   {,max}{,8}表示出现8次或者8次以下.

   5) () 如果想比对一串字符,而不单单是一个字符时,用小括号括起来.
 
   my $answer = "(wow)+";  比较字符串中是否还有wow这串字符

九, 正则表达式更多概念
  
   1) 正则表达式中的 "或 |"
   /f(oo|ee)t/    # 找 foot 或 feet
   /it (is|was) a good choice/  # 在句子中用不同的字
   /on (March|April|May)/   # 顯然也可以多個選擇
 
   2) 集合 []

   (/a|b|c|d|.......|z|A|B|C|D|......|_|) = [a-zA-Z_]

   集合中的特殊字元,-,^:

   在一个集合中比对“-”的时候前面必须加上转义字符“/” 例如要比对符号[!@#$%^&*()

_+/-=]
  
   在一个集合中,将“^”放到开头表示排除,例如 [^24680] 表示比对24680以外的字元

   3) 特殊符号
  
   /s:比对空白字符,可以处理(/n:换行 /t: 跳格TAB /f:换页 /r:回行首 )這五种字符留下的空白痕迹
   /S:在大部份的時候,正则表达式特殊字符的大小写总是表示相反的意思,例如我们使用/s來表示上面所说的五种空白字符,那么/S也就是排除以上五种字符。
 
   /w:等于[a-zA-Z]的集合,例如你可以比对长度为3到10的英文单字,那就要写成:
/w{3,10},同樣的,你就可以比對英文字母或英文單字了。
   /W:同样的,如果你不希望看到任何在英文字母范围里的字符,就用/W。
 
   /d:等于[0-9]的集合
   /D:[^0-9]:)

   例如:[a-zA-Z0-9_] = [/d/w_]

  4)/i : 忽略大小写
 
   $content =~ /perl/;  查找小写的
   $content =~ /Perl/;  查找大写的
   $content =~ /[pP]erl/;  查找大小写的
   $content =~ /perl/i;    也是查找大小写的

  5)my $content = "I like perl. /n I am a perl monger. /n";
     if ($content =~ /(like.*monger)/s) {
         print "$1/n";
     }
 
     . :萬用字元點號(.)
     $1:Perl的预设参数用来贮存比对的结果,如($1, $2, $3...)

6)Perl分配变量的方式則是根据左括号的位置来进行的。
     my $content = "I like perl. /n I am a perl monger. /n";
     if ($content =~ /((perl)/s(monger))/s) {
       print "$1/n$2/n$3/n";
     }

     输出:
     perl monger
     perl
     monger

  7^ 表示字串开始的时候。$ 表示字串结束的时候。
     /^Perl/ :希望比對某個字串一开始就是"Perl"这个字串儿, Perl is good.
     /Perl$/ :希望比對某個字串结束时才是"Perl"这个字串儿, This is a Perl.

   在一个集合中,将“^”放到开头表示排除,例如 [^24680] 表示比对24680以外的字元

十,正则表达式中的替换 s///
    
   s///来表示替換,其中第一部份表示比对的字串,第二部份则是要进行替换的部份
  
   s/比对的字串/替换的部份/
 
  1) /g 表示全部替换
 
   my $content = "水果對我們很有幫助,所以應該多吃水果";
   print $content if ($content =~ s/水果/零食/);  # 把水果用零食置換
 
   my $content = "水果對我們很有幫助,所以應該多吃水果";
   print $content if ($content =~ s/水果/零食/g);  # 把水果全部換成零食吧

   如果希望不管大小写替换,还可以加i, 如 /gi

  2) 一个互相交换的例子

   my $string = "lwh shi ge hao hai zi, ni shi ge huai hai zi";

   print $string if ($string =~ s/(lwh)(.*)(ni)(.*)/$3$2$1$4/);

  3)(?)來表示不贪多
    my $string "<table><tr><td>first</td></tr><tr><td>second</td></tr><tr><td>
third </td></tr></table>";

    if ($string =~ m|<tr><td>(.+?)<//td><//tr>|) {
       print "$1";
    }

    比对的结果竟然是 first, 为啥不是<tr><td>first</td></tr><tr><td>second</td></tr><tr><td>
third </td></tr>呢? 真奇怪???

  4)比对技巧,回溯參照 (backreference)
    不是很懂,有待学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值