zoukankan      html  css  js  c++  java
  • Perl 简介(适合对 C 语言有点认识的读者)

    1. Introduction
    这不是 perl 的完整介绍,只是想将 perl 向 C programmer 作个介绍,也许能
    有所帮助!
    perl 是由 Larry Wall 先生所写. 目前的版本 5.002, 加入多项的功能. 请
    看 perl.1, 那有详细的条列.
    一般而言, 由 awk, sed, shell programming 写的东西可以轻易用 perl 来
    处理,而且速度更快. 在 C program 中,特别是有关抽取文字档中的资讯,加以转化
    处理,用 perl 写会更加方便, 而且不用处处担心 pointer 和 memory allocation
    的问题. 当然了, perl 执行时会有一道转成内部表示式的关, 真正 optimized
    过的 C code 仍会比 perl code 快. 一般而言, perl code 会比 C code 短很多.
    perl 在 regular expression, list(array) 和 associative array 有很方
    便的语法和不错的执行效率. 连 yacc (Berkeley yacc) 也可有产生 perl code 的
    选项, 这对於 prototyping 十分方便.

    2. Perl Basics

    2.1 Basic data structure and Control construct
    perl 的 comment 是从 # 之後开始.而 perl 并不区分 string
    , integer 和 float point number 的 data type, 统统以纯量代表.例如:

    # This is a comment line till the end of this line
    $x=1.5;
    $y="I hate shell programming";
    $z=1.3e-27;

    这个 $ 是表示现在操作的是个纯量(相对於 list 或 associative array).
    在 C 里的 operator, 如 +,-,*,/,%,^,++,--,+=,-=,*=,/=,%=,==,!=, &&,
    ||, |, & 全都有, 意思也不变. 不过若用於字串, . (dot)是表示连接的意思.
    因此 .= 也有类似 C 中 += 的意思.

    $x='I hate ';
    $x.="awk programming.";
    print $x;

    结果为 I hate awk programming. 字串可用单或双括号围住. 超出一行也没关.
    也可以写的像 shell programming 中:

    $x= << END;
    This part can be put what
    you like here
    1234567890
    till the sign as the beginning.
    END
    相当於
    $x="This part can be put what
    you like here
    1234567890
    till the sign as the beginning.";

    字串的比较有 eq, ne, gt, lt, ....就像那 Fortran 的 operator. 聪明的
    你猜猜就知道啦.

    至於 control 方面, 如 if, while, do .. while, 都和 C 类似. 如:

    $sum=0;
    for($i=0;$i<10; $i++){
    $sum+=$i;
    }

    大括号是不可省略的! 这和 C 不同. 也可:

    $sum=0;
    $i=0;
    while($i<10){
    $sum+=$i++;
    }

    如果你要从 loop 中跳出来, last 相当於 C 中 break, next 相当於 continue.

    $sum=0;
    $i=0;
    while($i<10){
    if($i % 2==0){
    $sum+=$i++;
    next;
    }elsif($sum>50){
    last;
    }
    }

    if 叙述要注意大括号是不可省, 还有 else if 必须写成 elsif.

    2.2 List
    List 和 1 dimension array 在 perl 中没区别. 用法如:

    @a=(1,2,3);
    $a[0]-=$a[1];
    print "a[0]=$a[0]";

    结果就是 a[0]=-1. @是表示现在在操作 list. 双括号的字串中,若有变数, perl
    会直接解译. 如上例中的 $a[0]. List 可以直接连接:

    @a=(1,2,3);
    @b=(4,5);
    @c=(@a,@b,6,7);
    print "@c";

    结果是 1 2 3 4 5 6 7. perl 有特殊的变数, $#a 来表示 @a 的最後 index,
    所以上例中, $c[$#c] 就是 7, 也可写成 $c[-1]. 那麽 $c[-2] 就是 6 了.

    List 还有些 operator, push, pop, shift, unshift, splice, 其中
    push 推一些元素入 list:

    @a=(1,2);
    push @a,(3,4);
    结果 @a 成为 (1,2,3,4).

    pop 繽最後一个元素 :
    @a=(1,2,3);
    $b=pop @a;
    结果 @a 成为 (1,2), $b 变成 3.

    shift, unshift 和 pop, push 类似不过操作在 list 前端.
    @a=(1,2,3);
    $b=shift @a;
    unshift @a,0;
    结果 @a 成为 (0,2,3), $b 变成 1.

    Loop 也可写成:

    @weekday=( 'Mon','Tue','Wed','Thu','Fri','Sat');
    foreach $x(@weekday){
    # schedule something
    }
    结果 $x 会依序变成 'Mon','Tue','Wed','Thu','Fri','Sat' 等.



    2.3 Associative Array
    这是使用 string 来做 index 的 array, 一般叫作 hash.

    $phone_no{'peter'}='02-9110238';
    $phone_no{'john'}="06-1234567";
    $name='peter';
    print "$name Phone No.=",$phone_no{$name},"\n";

    结果就会印一行:
    peter Phone No.=02-9110238

    上面两行也可写成:
    %phone_no=( 'peter' => '02-9110238', 'john' => '06-1234567');
    => 和 , 一样所以:
    %phone_no=( 'peter' , '02-9110238', 'john' , '06-1234567');
    也可, 就是相当於一个 key 和 value, 所组成的list.

    2.4 Subroutine
    副程式可以任意摆放, perl 全看得到.

    sub foo{
    my $x=$_[0];
    my $y=$_[1];
    return $x/$y;
    }
    $x=1;
    $y=8;
    print foo(4,2);
    结果是 2.

    上例中, my 这个 keyword 表示, $x, $y 是在 foo 围内有效 (local variable
    in subroutine lexical scope).而 $_[0], $_[1] 用於传参数. perl 的 subroutine
    呼叫参数都是放在固定 @_ 的 list 中.

    2.5 Special Variables
    perl 常使用的 default variable 是 $_.

    @weekday=( 'Mon','Tue','Wed','Thu','Fri','Sat');
    foreach (@weekday){
    # do with $_
    }

    结果 $_ 会依序变成 'Mon','Tue','Wed','Thu','Fri','Sat' 等.

    @ARGV 是 perl 执行时的 command line argument,$ARGV[0] 相当於 C 中的
    argv[1]. $ARGV[1] 相当於 C 中的 argv[2]. C 中的 argv[0] 放在 $0.
    %ENV 是 perl 执行时的 environment variable, $ENV{'HOME'} 就是 user
    的 home path, $ENV{'PWD'} 就是 current path.

    其它特殊变数请参考 perlvar.1.


    2.6 File Handle
    perl 中主要开档的方法:

    PrivoxyWindowOpen(FH,"test.dat"); # 写入
    PrivoxyWindowOpen(FH,"grep peter test.dat|"); # 先綺 grep peter test.dat 处理後的 pipe 资料
    PrivoxyWindowOpen(FH,"|more"); # 後綺 more 处理写出的资料

    $oneLine=; # 读取 FH
    print FH "1234"; # 写入 FH

    close(FH); # 关档

    例子:
    PrivoxyWindowOpen(FH,"test.dat"); # 相当於 PrivoxyWindowOpen(FH, "){
    printf "%4d:%s",++$n,$_;
    }
    close(FH);
    结果会把 test.dat 加 4 位行号印出.( 只写 时相当於省略 $_= ).


    2.7 Regular Expression
    perl 对於 regular expression 有重新改写. 好用且功能强, 是 sed 和 awk 的
    superset. 要求执行 regular expression 比对的 operator 为 ~= ( match),
    != ( not match). regular expression 用 /.../ 括住.

    $line=" end; ";
    if($line =~ /end/){
    print "match!";
    }else{
    print "NO!";
    }
    结果会印出 match!, 如果改成
    if($line =~ /^end/){
    print "match!";
    }else{
    print "NO!";
    }
    结果会印出 NO!

    一般而言,
    ^ 表string 的开端,
    $ 表string 的结束,
    [a-z] 表 a 到 z 中任一字元
    pat1 | pat2 表 pat1 或 pat2 皆可
    x* 表 x 重 0 次或以上
    x+ 表 x 重 1 次或以上
    \d 相当於 [0123456789], \D 就是相反
    \w 相当於 [_a-zA-Z0-9], \W 就是相反
    \s 表示 space, \S 表非 space character

    若要取代,则:
    $d="Sep. 15th, Sep. 17th";
    $a =~ s/Sep/9/;
    结果是 9. 15th, Sep. 17th, 加 g (global) option 如下:
    $d="Sep. 15th, Sep. 17th";
    $a =~ s/Sep/9/g;
    结果是 9. 15th, 9. 17th. 另外 i (case-insensitive) option 可不管大小写.

    2.8 Reference
    Perl 5.0 之後允许 list of list 也就可能有 2-Dimension Array.
    例如:

    $a[0][0]=1;
    $phone{$name}[0]='1234';
    $phone{$name}[1]='2674';

    实际上 是用所谓的 reference,就像是 C 的 address. 一个纯量可纯存一个
    reference.

    @a=(1,2,3);
    $aref=\@a; # 取 @a 的 reference
    print $aref->[0]; # 相当於 print $a[0];
    push @{$aref},4; # 相当於 push @a,4;

    2-dimension array 可以如:
    @a=([1,2,3],[4,5,6]);
    print $a[1][2];
    结果是 6.

    使用 associative array 也类似:
    $database{$name}{'home'}{'address'}='No. 1234, 75th Street";
    $database{$name}{'office'}{'phone'}='02-8127365";

    List of associative array 也都可以使用.

    2.9 Example
    Email 中若有 uuencode 的资料,可以写 perl 将它 extract 出来.

    #!/usr/local/bin/perl
    PrivoxyWindowOpen(EMAIL,"<$ARGV[0]")||die "Cannot open $ARGV[0]:$!";
    # 若开不成 perl 会跳出且印 Cannot open ...
    while(){
    if(/^begin\s+\d\d\d\s+/){
    # 遇到 begin 开头後印出
    print $_;
    while(){
    if(/^end/){
    # 遇到 end 时结述
    last;
    }
    print $_;
    }
    print $_;
    last;
    }
    }
    close(EMAIL);
    可以写得更简化,不过那就属於您功力的无限空间了......

  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/ma/p/444980.html
Copyright © 2011-2022 走看看