美文网首页
Perl基础

Perl基础

作者: 曹元_ | 来源:发表于2021-04-12 01:58 被阅读0次

    Perl是什么

    一、Perl 简介

    Perl,一种功能丰富的计算机程序语言,运行在超过100种计算机平台上,适用广泛,从大型机到便携设备,从快速原型创建到大规模可扩展开发。

    Perl 语言的应用范围很广,除CGI以外,Perl被用于图形编程、系统管理、网络编程、金融、生物以及其他领域。由于其灵活性,Perl被称为脚本语言中的瑞士军刀。


    二、什么是 Perl?

    Perl是由Larry Wall设计的,并由他不断更新和维护的编程语言。

    Perl具有高级语言(如C)的强大能力和灵活性。事实上,你将看到,它的许多特性是从C语言中借用来的。

    Perl与脚本语言一样,Perl不需要编译器和链接器来运行代码,你要做的只是写出程序并告诉Perl来运行而已。这意味着Perl对于小的编程问题的快速解决方案和为大型事件创建原型来测试潜在的解决方案是十分理想的。

    Perl提供脚本语言(如sed和awk)的所有功能,还具有它们所不具备的很多功能。Perl还支持sed到Perl及awk到Perl的翻译器。

    简而言之,Perl像C一样强大,像awk、sed等脚本描述语言一样方便。


    三、Perl 优点

    • 相比C、Pascal这样的"高级"语言而言,Perl语言直接提供泛型变量、动态数组、Hash表等更加便捷的编程元素。

    • Perl具有动态语言的强大灵活的特性,并且还从C/C++、Basic、Pascal等语言中分别借鉴了语法规则,从而提供了许多冗余语法。

    • 在统一变量类型和掩盖运算细节方面,Perl做得比其他高级语言(如:Python)更为出色。

    • 由于从其他语言大量借鉴了语法,使得从其他编程语言转到Perl语言的程序员可以迅速上手写程序并完成任务,这使得Perl语言是一门容易用的语言。

    • Perl 是可扩展的,我们可以通过CPAN("the Comprehensive Perl Archive Network"全面的 Perl 存档网络)中心仓库找到很多我们需要的模块。

    • Perl 的 mod_perl 的模块允许 Apache web 服务器使用 Perl 解释器。


    四、Perl 缺点

    也正是因为Perl的灵活性和"过度"的冗余语法,也因此获得了仅写(write-only)的"美誉",因为Perl程序可以写得很随意(例如,变量不经声明就可以直接使用),但是可能少写一些字母就会得到意想不到的结果(而不报错),许多Perl程序的代码令人难以阅读,实现相同功能的程序代码长度可以相差十倍百倍,这就令程序的维护者(甚至是编写者)难以维护。

    同样的,因为Perl这样随意的特点,可能会导致一些Perl程序员遗忘语法,以至于不得不经常查看Perl手册。

    建议的解决方法是在程序里使用use strict;以及use warnings;,并统一代码风格,使用库,而不是自己使用"硬编码"。Perl同样可以将代码书写得像Python或Ruby等语言一样优雅。

    很多时候,perl.exe进程会占用很多的内存空间,虽然只是一时,但是感觉不好。

    Perl入门

    一、数据类型(Data Type)

    Perl的数据类型大致可以分为四类:Scalar(标量)、Array(数组)、Hash(哈希)以及Reference(引用)。

    1、Scalar(标量)

    标量是Perl中最简单的一种数据类型,也是构成其他三个数据类型的基石。标量变量可以代表一个字符、字符串以及数字(整数或浮点数)。

    1-1、数字

    在Perl内部,它总是以“双精度浮点数(double-precision floating-point)”的要求来保存数字并进行运算。

    浮点数直接量

    1.25
    255.000
    7.25e45
    -6.5e24
    

    整数直接量

    Perl允许我们在整数直接量中插入下划线

    0
    2001
    -4
    61_298_040
    

    非十进制的整数直接量

    八进制(octal)直接量以0开头,十六进制(hexadecimal)直接量以0x开头,二进制(binary)直接量以0b开头。十六进制的A到F(or a到f)代表十进制的10到15

    0377 # 八进制的377,等于十进制的255
    0xff  # 十六进制的FF,等于十进制的255
    0b11111111   # 二进制,等于十进制的255
    0x50_65_72_7c  #十六进制
    

    1-2、字符串

    单引号内的字符串直接量

    在单引号内的字符串直接量除了单引号和反斜线字符外,单引号内所有字符都代表它们自己(包括换行符)。如需代表反斜杠字符本身,需要再反斜线字符前再加一个反斜线字符表示转义

    'fred'   # 总共4个字符:f,r,e,d
    'hello\n' #hello后面接着反斜线和字母n
    '\'\\'  # 单引号紧接着反斜线(总共2个字符)
    

    双引号内的字符串直接量

    双引号中的反斜线可以转义许多控制字符,或是用八进制或十六进制写法来表示任何字符。

    "hello world\n"   # hello world,后面接着换行符
    coke\tsprite  # coke、制表符(tab)和sprite
    \x{2668}  # Unicode中名为HOT SPRINGS的字符的代码点(code point)
    

    双引号内字符串的反斜线转义

    组合 意义
    \n 换行
    \r 回车
    \t 水平制表符
    \f 换页符
    \b 退格
    \a 系统响铃
    \e ESC(ASCII编码的转义字符)
    \007 八进制表示的ASCII值(此例中007表示系统响铃)
    \x7f 十六进制表示ASCII值(此例中7f表示删除键的控制代码)
    \x{2744} 十六进制表示的Unicode代码点(这里的U+2744表示雪花形状的图形字符)
    \cC 控制符,也就是Control键的代码(此例表示同时按下Ctrl键和C键的返回码)
    \ 反斜线
    \ 双引号
    \l 将下个字母转为小写的
    \L 将它后面的所有字母都转为小写的,知道\E为止
    \u 将下个字母转为大写的
    \U 将它后面的所有字母都转为大写的,知道\E为止
    \Q 相当于把它到\E之间的非单词(non word)字符加上反斜线转义
    \E 结束\L、\U和\Q开始的作用范围

    字符串操作符

    字符串连接(.)

    "hello" . "world"  # 等同于"helloworld"
    'hello world' . "\n" #等同于"hello world\n"
    

    字符/字符串重复(x)

    "fred" x 3  # 得"fredfredfred"
    5 x 4.8 #本质上就是 5 x 4, 得 "5555"
    

    Perl会根据需要,自动在数字和字符串之间进行类型转换。是否发生转换由操作符决定,如果操作符(如+)需要的是数字,Perl就回将操作数视为数字;在操作符(比如.)需要字符串时,Perl便会将操作数视为字符串。

    # “前置零”的技巧只对直接量有效
    0377  # 十进制数字255的八进制写法
    '0377'  # 会转换成十进制数字377
    "Z" . 5 * 7  # 等同于"Z".35,得"Z35"
    

    2、List(列表)和Array(数组)

    列表(list)指的是标量的有序集合,数组(array)是存储列表的变量。更精确的说,列表指的是数据,而数组指的是变量。

    2-1、列表

    列表是包含在括号里的一序列的值,可以为任何数值,也可为空

    (1,2,3)  # 包含1、2、3三个数字的列表
    ( )   # 空列表——0个元素
    (1..100)  # 100个整数构成的列表
    ("fred","barney","betty","wilma","dino")
    

    qw简写可以省去键入无谓引号的麻烦,定界符(delimiter)可以hi任何标点符号,如:()、!、/、#、{}、[]、…

    qw( fred barney betty wilma dino )
    qw! fred barney betty wilma dino !
    qw/ fred barney betty wilma dino /
    qw# fred barney betty wilma dino #
    

    列表的赋值:

    ($fred, ¥barney, $dino)=("A", "B", "C")
    

    2-2、数组

    列表存贮于Perl数组变量中,与简单变量不同,Perl数组变量以字符”@”打头,如

    @array=(1,2,3);
    

    注:
    (1)Perl数组变量创建时初始值为空列表:()。
    (2)Perl中数组变量和标量标量处于不同的命名空间,所以同一个变量名可以同时用作数组变量和标量变量而不用担心命名冲突。所以同一个名字可以同时用于Perl数组变量和简单变量
    数组中元素可以通过下标操作符[]表示,第一个元素的下标为0,最后一个元素的下标为-1。试图访问不存在的数组元素将得到undef,如果给超出数组大小之外的元素赋值,则Perl数组将自动增长,原来没有的元素的值为undef。如下:

    my @arr = (1, 2, 3);
    my $var = $arr[5];  # $var will get undef
    $arr[5] = 8;      # @arr changes to (1,2,3,undef,undef,8)
    

    最后一个元素的索引值是$#rocks

    3、Hash(哈希)和散列

    哈希是一种数据结构,它和数组的区别在于:不像数组以下标来检索元素,哈希使用键来检索元素。哈希结构中每一个元素都有一个键和一个值,键必须唯一。

    my %hash = (1 => "fred", 2.5 => 1, "fred" => 2.5);
    

    符号”=>” 在Perl中被戏称为胖箭头,它很好的展示了哈希结构中键与值的映射关系。
    在Perl中胖箭头”=>”与逗号”,”是完全等价的,因此上面右边的散列中的胖箭头完全可以用逗号代替。使用胖箭头的唯一理由就是它清晰的表达了各个键与值映射关系。

    访问哈希元素:$hash{$some_key}
    访问整个哈希:%family_name
    哈希赋值:my %new_hash = %old_hash
    建立一个反序的哈希:my %inverse_hash = reverse %any_hash

    4、引用(reference)和地址

    应该说引用使得Perl中数组和哈希变的更加灵活而强大。引用表达的是一种“指向”的关系,因此它类似于C语言中的指针。比如你创建一个引用让它指向一个数组:

    my $ref1 = \@arr;
    my $ref2->[0] = "first";
    $ref2->[2] = 3;
    

    这两种方法都会创建一个引用,第一个方法要求数组@arr已经被声明。第二种方法更像是创建了一个类似于数组的怪物,之所以说它是怪物是因为你如果需要访问数组的某个元素,你只能使用箭头符号”->”来完成下标的指定,类似于:

    my $var = $ref->[num];
    

    这里num显然是一个整数值。一般来说,引用的创建多用来指向到一个数组或者一个哈希。创建一个引用指向一个标量似乎没有太大的必要。
    有了引用,我们就可以使用标量、数组以及哈希来任意地构造我们的数据结构,比如:

    my $arr_double->[0] = \(1, 2, 3);
    $arr_double->[1] = \(4, 5, 6);
    $arr_double->[2] = \(7, 8, 9);
    my $hash_double->{'line1'}->{'row1'} = "first";
    $hash_double->{'line1'}->{'row2'} = "second";
    

    二、运算符及其优先级

    Perl下的运算符来基本上借鉴于两种语言:C与Pascal。全部的运算符及其结合性如下:
    表2-1  Perl中操作符

    操作符 结合性 完成的操作
    () 改变运算的优先级;列表操作符
    -> 引用操作符
    ++ – ++自增,–自减
    ** 乘幂
    \ ! ~ + - 都是单目操作符,\取地址,!逻辑非,~按位非,+正号,-负号
    =~ !~ =匹配绑定操作符,!不匹配绑定操作符(这东西太诡异了)
    * / % x *乘,/除,%求余,x字符串重复操作符
    << >> 移位操作符
    -X -r rand shift 具名的单目操作符,-X与-r都是文件测试操作符,rand得到一个随机值
    < <= > >= lt le gt ge “不等”关系运算符,前四个比较数值,后四个比较字符串
    == != <=> eq ne cmp “相等”关系操作符,前三个比较数值,后三个比较字符串
    & 按位与
    ^ 按位或,^按位异或
    && 逻辑与
    .. … ..范围操作符,
    ?: Perl中最诡异的操作符:三目(条件)操作符
    = += x= .= 赋值以及增量赋值操作符
    , => 逗号操作符;列表操作符(右结合性)
    not 逻辑非
    and 逻辑与
    or xor or逻辑或,xor逻辑异或

    如你所见,Perl中操作符很多很多,而且有很多冗余的,比如逻辑操作符有两套,and/not/or/xor系之所以存在,是因为它们的优先级很低,这 样使用它们有时你可以省敲一些括号。全部记住这些操作符及其优先级和更加让人头疼的结合性显然是不现实的,并且也有悖于Perl程序懒惰的作风,所以合理 的使用圆括号是值得推荐的,也很有必要。

    三、关于context(上下文)

    上下文是一种很重要的概念,尽管我们未必留意到它,但是我们却无时无刻不在使用它。比如,某次考试后,你问别人“嘿,第21题怎么回事?”,你的同学应该可以立刻直到你在问什么。但如果你把这句话同样的说给刚刚睡醒爷爷听,他一定会感到莫名其妙。这就是上下文的概念。
    在Perl中,上下文就是概念就是:同一个表达式,出现在不同的地方会有不同的结果和意义。
    我们直到Perl中最最常见的就是标量和列表了,这形成了Perl中两种最常见上下文环境:标量上下文和列表上下文。标量上下文中的表达式被期望返回一个标量值,而列表上下文中的表达式则被期望返回一个列表。

    1、在标量上下文中使用产生列表的表达式

    这个情况没有统一的规定,但是,大多数情况下会返回列表元素的个数,这基本上就是你期望的。尽管如此,我还是打算详细说明一些比较“特殊”的。
    某些表达式不会在标量上下文中返回任何值。比如,sort在标量上下文中返回的是undef。有人或许会认为应该返回列表元素的个数,可是谁会通过对列表排序来获得列表的个数呢?
    某些表达式在标量上下文中会返回列表所有元素连接而成的串。比如reverse,在标量上下文中,它会返回逆序后的字符串(先将列表中所有元素串连在一起,在对结果进行反序处理)。

    @letters = reverse qw/A B C D E/; # 会得到E,D,C,B,A
    $letters = reverse qw/A B C D E/;  # 会得到EDCBA
    

    另外需要强调的是,对于print操作符,其后是一个列表上下文。

    2、在列表上下文中使用产生标量的表达式

    这种情况十分简单:如果表达式求值结果为标量值,则自动产生一个仅含此标量值的列表

    @fred = 6 * 7; # 得到仅有单个元素的列表(42)
    @barney = "hello" . ' ' . "world";
    @wilma = undef # 结果会得到一个列表,而且仅有的一个元素为未定义的(undef)
    @betty = ( );  # 正确的清空数组的方法
    

    因为undef是标量值,所以将undef赋值给数组并不会清空该数组。要清空的话,直接赋予一个空列表即可。

    3、强制指定标量上下文

    在Perl想要列表上下文的地方你想要强制引入标量上下文,可以使用为函数scalar。它不是真正的函数,只是告诉Perl这里要切换到标量上下文。

    @rocks = qw( talc quartz jade obsidian );
    print "How many rcks do you have?\n";
    print "I have ", @rocks, "rocks!\n"; #wrong,这里会输出各种石头的名称
    print "I have ", scalar @rocks, "rocks!\n"; # right,打印出来的是石头种数
    

    四、语句结构

    1、判断条件和“布尔”值

    Perl中没有专用的布尔类型的值,关系运算的结果也会是一个标量值,Perl中任何标量值都可以作为控制结构的判断条件。Perl中判定一个标量为真还是假的规则很简单:
    (1)如果值为数值,0为假,所有其它数值为真;
    (2)如果值为字符串,空字符串(”“或”)为假,所有其它字符串为真;
    (3)如果不是数值也不适字符串,那么就先转化成数值或字符串再进行判断,所以undef为假,所有的引用都为真;
    需要注意的一点就是:字符串’0’或”0”跟数字0是同一个标量值,所以也为假,这是非空字符串为假的唯一的例外。
    对于列表,现将它转化成标量值在进行判断(也就是说控制结构的判断条件是一个标量上下文)。

    2、条件控制结构

    2-1、if控制结构

    if (condition1){
        something;
    } elsif (condition2) {
        someting;
    } else {
        something;
    } 
    

    注意,Perl中控制结构的花括号不是可有可无的,而是必须存在的。Perl中暂时没有switch结构,在Perl6中或许会有这个结构。其它分支选择结构还有unless结构,只是比较少用。

    为了进一步简化代码书写,表达式后面可以接一个用于控制它行为的修饰符。比如

    print "$n is a negative number.\n" if $n < 0;
    

    2-2、unless控制结构

    unless (condition) {
        something;
    } else {
        something;
    }
    

    2-3、条件操作符 ? :

    条件操作符就像将一个if-then-else控制结构。

    expression ? if_true_expr : if_false_expr
    

    3、循环控制结构

    3-1、while控制结构

    while (condition){
        something;
    }
    

    3-2、裸块控制结构

    裸块就像一个while或foreach循环,只是它从不循环,它仅仅执行循环体一次,然后结束。所以裸块其实并非循环。裸块的结构如下:

    {
        body;
        body;
        body;
    }
    

    3-3、until控制结构

    until (condition) {
        something;
    }
    

    3-4、foreach循环控制结构

    foreach $var (@array) {
        something;
    }
    

    3-5、for 循环结构

    for (initialization;condition;increment) {
        something;
    }
    

    3-6、循环控制

    last操作符

    last操作符能立即中止循环的执行,就像C这类语言中的”break”操作符一样。

    # 打印输入中所有提到 fred 的行,直到碰到 _END_ 记号为止
    while (<STDIN>) {
        if(/_END_/) {
            # 碰到这个记号说明再也没有其他输入了
            last;
        } elsif (/fred/) {
            print;
        }
    }
    

    next操作符

    有时候我们并不需要立刻退出循环,但需要立刻结束当前这次循环迭代。next操作符的用处就是它会跳到当前循环块的底端。在next之后,程序将会继续执行循环的下一次迭代,这和C这类语言中的”continue”操作符功能相似

    # 分析输入文件中的单词
    while {<>} {
        foreach (spilt) {
            $total++;
            next if /\W/;
            $valid++;
            $count{$_}++;
            ## 上面的next语句如果运行,会跳到这里 ##
        }
    }
    print "total things = $total, valid words = $valid\n";
    foreach $word (sort keys %count) {
        print "$word was seen $count{$word} times.\n";
    }
    

    redo操作符

    redo能将控制返回到当前循环块的顶端,而不经过任何条件测试,也不会进入下一次循环迭代。

    # 打字测验
    my @words = qw{ fred barney pebbles dino wilma betty };
    my $errors = 0;
    
    foreach (@words) {
        ## redo 指令会跳到这里##
        print "Type the word '$_':";
        chomp(my $try = <STDIN>);
        if ($try ne $_) {
            print "Sorry - That's not right.\n\n";
            $errors++;
            redo; #跳到循环顶端
        }
    }
    print "You've completed the test, with $errors errors.\n";
    

    next和redo两者之间最大的区别在于,next会正常继续下一次迭代,而redo会重新执行这次迭代。

    五、函数

    1、list的操作函数

    1-1、 pop和push

    pop和push操作符是对数组的“尾端”进行处理
    pop操作符:取出数组中最后一个元素并将其作为返回值返回,常用于删除数组中的最后一个元素

    @array = 5..9;    #原数组array是(5,6,7,8,9)
    $fred = pop(@array); #$fred 变成9, @array现在是(5,6,7,8)
    $barney = pop @array; #$barney 变成8,@array现在是(5,6,7)
    

    注:如果数组是空的,pop什么也不做,直接返回undef

    push操作符:添加一个元素(或一串元素)到数组尾端

    @array = (5,6);
    push (@array, 0);  # @array现在是(5,6,0)
    push @array, 8;  # @array现在是(5,6,0,8)
    push @array, 1..10;  # @array得到了10个新元素
    @others = qw / 9 0 2 1 0/;
    push @array, @others; # @array又得到了5个新元素 
    

    1-2、shift和unshift

    shift和unshift操作符是对数组的“开头”进行相应的处理

    @array = qw/ dino fred barney /;
    $m = shift(@array);  # $m变成"dino",@array现在是("fred","barney")
    $n = shift @array;  # $n变成"fred", @array现在是("barney")
    shift @array;  # 现在@array变空了
    $o = shift @array;  # $so变成undef,@aaray还是空的
    unshift (@array, 5);  # @array现在仅包含一个元素的列表(5)
    unshift (@array, 4);  # @array现在是(4, 5)
    @others = 1..3;
    unshift @array, @others;  # @array现在是(1,2,3,4,5)
    

    1-3、splice

    splice操作符是对数组“中间”进行相应的处理
    splice可接受4个参数:

    splice x1, x2, x3, x4
    
     - x1:要操作的目标数组
     - x2:要操作的一组元素开始的位置
     - x3:指定要操作的元素长度
     - x4:要替换的列表
    

    示例1:

    @array = qw( A B C D E );
    @removed = splice @array, 2; #在原来的数组中删掉C及其后的元素
                                 #@removed变成qw(C D E)
                                 #原先的@array变成 qw(A B)
    

    示例2:

    @array = qw( A B C D E );
    @removed = splice @array, 1, 2, qw(F); #删除B和C
                                           #@removed变成qw(B C)
                                           #@array变成qw(A F D E)
    

    示例3:

    @array = qw( A B C D E );
    @removed = splice @array, 1, 0,qw(F); #什么元素都不删
                                         #@removed变成qw()
                                         #@array变成qw(A F B C D E)
    

    1-4、reverse

    reverse操作符会读取列表(或数组)的值,并按相反的次序返回该列表
    示例:

    @fred = 6..10;
    @barney = reverse(@fred); #得10,9,8,7,6
    @wilma = reverse 6..10; #同上
    @fred = reverse @fred; #将逆序后的结果放回原来那个数组
    

    注:reverse会返回次序相反的列表,但它不会修改传进来的参数。假如返回值无处可去,那么操作也是无意义的。

    reverse @fred #错误——这不会修改@fred的值
    

    1-5、sort

    sort操作符会读取列表(或数组)的值,根据内部的字符编码顺序对它们进行排序。对字符串而言,就是字符在计算机内部表示的代码点。
    示例:

    @rocks = qw/ bedrock slate rubble granite /;
    @sorted = srot(@rocks); #得bedrock,granite,rubble,slate
    

    注:与reverse操作符一样,你必须将排序后的结果存回数组

    1-6、each

    对数组调用each,会返回数组中下一个元素所对应的两个值——该元素的索引以及该元素的值。

    use 5.012
    my @rocks = qw/ bedrock slate rubble granite /;
    while( my( $index,$value ) = each @rocks){
        say "$index:$value";
    }
    

    如果不用each来实现,可以根据索引从小到大依次遍历,然后借助索引值取得元素的值

    @rocks = qw/ bedrock slate rubble granite /;
    foreach $index ( 0..$#rocks ){
        print "$index:$rocks[$index]\n";
    }
    

    2、哈希的操作函数

    2-1、keys 和 value函数

    keys函数会返回此hash的所有keys,values函数将返回所有的values。如果hash中没有元素,则此函数将返回空列表。

    my %hash = ("a"=>1, "b"=>2, "c"=>3);  
    print my @k = keys %hash;  
    print my @v = values %hash;  
    

    2-2、each函数

    如果想迭代hash的每一个元素,一种通常的方法是使用each函数,它将返回key/value对应的2个元素列表。
    当对同一个hash 函数进行一次迭代时,将返回下一个key/value对,直到所有的元素均被访问。如果没有更多的key/value对,则each函数将返回空表。

    my %hash = ("a"=>1, "b"=>2, "c"=>3);  
    while(($key, $value) = each %hash)  
    {  
    print "$key => $value\n";  
    }  
    

    当然,each返回的key/vlaue对,顺序是混乱的(它其顺序和keys和values函数返回的顺序相同)。如果想将其按序排放,可以对它们排序(使用sort)。

    my %hash = ("a"=>1, "b"=>2, "c"=>3, "d"=>4);  
    foreach $key (sort keys %hash)  
    {  
    $value =$hash{$key};  
    print "$key => $value\n";  
    }  
    

    2-3、exists函数

    要查看hash中是否存在某个key,可以使用exists函数,如果hash中存在此key,则返回true,与是否有对应的value无关。

    my %hash = ("a"=>1, "b"=>2, "c"=>3, "d"=>4);  
    if(exists $hash{'a'})  
    {  
    print "true";  
    }  
    

    2-4、delete函数

    delete函数将某个给定的key(包括其对应的value)从hash中删除。如果不存在这个key,则什么也不做,不会有警告或者错误信息。

    my %hash = ("a"=>1, "b"=>2, "c"=>3, "d"=>4);  
    delete $hash{'a'};  
    foreach $key (sort keys %hash)  
    {  
    $value =$hash{$key};  
    print "$key => $value\n";  
    }  
    

    3、子函数

    函数以关键词sub申明,结构如下:

    sub function_name {
        something;
    }
    

    调用函数的方法如下:

    &function_name(parameter_list);
    

    对于函数,需要注意的是在调用时,函数的参数是一个列表上下文,所以才叫做参数列表嘛。传给函数的参数被放在函数的下划线变量@_中。Perl中函数的返回值可以通过return语句显示返回,如果没有return语句,则返回最后一个条语句的执行结果。

    4、字符串操作函数

    4-1、chomp

    chomp操作符只能作用于单个变量,且该变量的内容必须为字符串,如果该字符串末尾是换行符,chomp()的任务就是去掉它。

    chomp($text = <STDIN>);
    

    4-2、split

    split是使用正则表达式的操作符,它会根据给定的模式拆分字符串。对于使用制表符、冒号、空白或任意符号分隔不同字段数据的字符串来说,用这个操作符分解提取字段相当方便。

    my @fields = split /separator/, $string;
    

    例:

    my @fields = split /:/, "ab:cde:f";   # 得到("ab", "cde", "f")
    

    4-3、join

    joint函数不会使用模式,它的功能与split恰好相反,join会把几个子字符串结合成一个字符串。

    my $string = join $glue, @pieces;
    

    join的第一个参数可以是任意字符串,弃于参数则是一串片段。

    my @x = join ":", 4,6,8,10;   # $x 为 "4:6:8:10"
    

    4-4、index

    index的作用是找出子字符串在主字符串中的相对位置

    $where = index($Main_String, $Sub_String, $intial_position);
    

    Perl会在Main_String字符串 中寻找Sub_String字符串首次出现的地方,并返回一个整数表示第一个字符的匹配位置,返回的字符位置从0算起。即:如果子字符串时在字符串最开始的位置找到,那么index会返回0。第三个参数 $intial_position 可以指定开始搜索的地方

    4-5、substr

    substr函数只处理较长字符串中的一小部分内容

    my $part = substr($string, $intial_position, $length);
    

    它的三个参数为:一个原始字符串、一个从零起算的起始位置,以及子字符串长度。

    5、格式化输出函数

    5-1、 print

    print函数作用:接受标量值作为参数,然后不经修饰的将它传送到标准输出。

    print "hello, world! \n";
    

    5-2、printf

    printf的参数包括“格式字符串”及“要输出的数据列表”。

    printf "Hello, %s; Your password expires in %d days!\n", $user, $days_to_die;
    
    格式 作用
    %g 输出数字,它将根据需要自动选用浮点数,整数或者指数
    %d 十进制整数,它会舍去小数点之后的数字。非四舍五入
    %x 十六进制
    %o 八进制 根据需要截尾
    %s 字符串格式,可以设定字段宽度。宽度字段如果是正数代表向右对齐,负数是相左对齐如%10s, %-15s
    %f 针对数字的,转换格式(浮点数),会按需求四舍五入。如%12.3f (表示输出共12个字符,包括小数点,并且小数点后面只有3位数)
    %% 输出百分号,不会使用后面列表中的元素

    例子:

    printf "%g %g %g\n", 5/2, 51/17, 51 ** 17; #2.5 3 1.0683e+29
    printf "in %d days!\n", 17.85; #in 17 days!
    printf "%6d\n",42  #从输出结果看起来像````42(符号`代表空格)
    printf "%2d\n", 2e3 + 1.95; #2001
    printf "%10s\n", "wilma"; #看起来像`````wilma
    printf "%-15s\n", "flintstone"; #看起来像flintstone`````
    printf "12f\n", 6*7 + 2/3; # ```42.66667
    printf "12.3f\n", 6*7 + 2/3; # ``````42.667
    printf "12.0f\n", 6*7 + 2/3; # ``````````43
    

    5-3、sprintf

    sprintf函数与printf有相同的参数(可选的文件句柄参数除外),但它返回的是所请求的字符串,而不会直接打印出来。你可以将格式化后的字符串存在变量里以便稍后使用。此外,你也可以对结果进行额外的处理,而单靠printf是做不到这些的

    sprintf FORMAT, LIST
    

    FORMAT 包含一个带有嵌入的域指示符的文本,LIST 里的元素就是逐一替换到这些域中去的。sprintf 的格式:

    含义
    %% 一个百分号
    %c 一个带有给定数字的字符
    %s 一个字串
    %d 一个有符号整数,十进制
    %u 一个无符号整数,十进制
    %o 一个无符号整数,八进制
    %x 一个无符号整数,十六进制
    %e 一个浮点数,科学记数法表示
    %f 一个浮点数,用固定的小数点表示
    %g 一个浮点数,以 %e 或 %f 表示

    另外,Perl 允许下列广泛支持的转换:

    含义
    %x 类似 %x,但使用大写字符
    %E 类似 %e,但使用大写的“E”
    %G 类似 %g,但是带一个大写的“E”(如果正确的话)
    %b 一个无符号整数,二进制
    %p 一个指针(输出十六进制的 Perl 值的地址)

    最后,为了向下兼容(我们的意思就是“向下”),Perl 允许下列不必要的但广泛支持的转换:

    含义
    %i %d 的同义词
    %D %ld 的同义词
    %U %lu 的同义词
    %O %lo 的同义词
    %F %f 的同义词

    六、总结:常用符号、用法、函数、库

    1、数据操作

    • $ : 声明与引用一个scalar的变量
    • @: 声明与引用一个list/数组,但是当访问一个list/数组的成员时,使用$ListName[index]
    • %: 声明与引用一个hash表,当访问一个hash的成员时,使用$HashName{key}

    2、特殊变量

    • $0:当前运行脚本的文件名
    • @ARGV:当前运行脚本的命令行参数列表
    • $_:默认变量,如循环中的当前变量
    • @_:函数的输入参数列表
    • %ENV:系统的环境变量
    • @INC:Perl的Include路径列表,我们可以往该列表中添加我们自己的目录来方便引用自定义的库
    • $!:当前系统提示,错误信息
    • $^O:操作系统的名字
    • $STDIN,STDOUT,STDERR:输入输出的默认句柄,可以做一定的自定义
    • =>:声明一个hash时可以用来明确的表示出key=>value的对应关系
    • $^I:指定备份的文件的后缀名。被修改的文件将自动以该后缀名保存一个副本

    3、特殊用法

    • &sub:调用一个函数,虽然Perl有些规则让你在某些时候可以省略这里的&符号,但是出于一致性考虑,自定义的函数调用一律采用此种方式
    • $#:用来取得某个数组的最大index。一般情况下,可以使用 - 1 来表示最后一个元素的index
    • qw():快速声明一个字符串数组,可以省略那些烦人的引号

    4、常用函数

    • list的操作函数:pop, push, shift, unshift, reverse
    • hash的操作函数:keys, values, exists,each, delete
    • 字符串操作函数:chomp, split, join, index, substr, sort
    • 格式化输出函数:sprintf, printf, print
    • 系统命令调用函数:system, exec, “
    • 文件系统操作函数:glob, unlink, mkdir, rmdir, rename, chmod, chown, open, close, opendir, closedir
    • 文档属性,时间相关函数:stat, lstat, localtime, gmtime,utime
    • 二进制,八进制,十六进制数转化成十进制的函数:hex, oct
    • list高级操作函数:grep,map

    注:这些函数的详细介绍都可以通过perldoc -f functionname 查到

    5、常用库

    • File::Basename:根据path获取文件名或者文件路径
    • File::Spec:格局文件名与路径组合成全路径
    • Fie::Find:递归遍历某个目录下所有文件
    • XML::Simple:以一个复杂的结构来表示xml文件,使用起来相当方便
    • Time::HiRes:当脚本需要复杂的输入参数与选项时用到
    • Cwd:拿到当前工作目录
    • IO::File:文件操作
    • Win32:当需要调用一些Windows API时用到它

    参考:
    1、http://www.cnblogs.com/hiflex/archive/2012/08/03/2621353.html
    2、《Perl语言入门》
    3、http://www.jb51.net/article/30473.htm
    4、http://www.perlcn.com/perlbc/perljj/1133.html

    相关文章

      网友评论

          本文标题:Perl基础

          本文链接:https://www.haomeiwen.com/subject/nvntfltx.html