zoukankan      html  css  js  c++  java
  • Perl语言入门1417

    ---------第十四章 字符串与排序-------------------

    index查找子字符串

    my $stuff = "howdy world!";
    my $where = index($stuff, "wor"); #6
    #返回首个字符匹配的位置,字符串第一个位置为0,上例即wor匹配的w位置
    #无法匹配返回-1
    
    my $here = index($stuff,"w",2); #返回2(从2+1个字符开始)
    my $there = index($stuff,"w",3); #返回6
    
    rindex从末尾开始找起,基本用不到
    

    substr操作子字符串

    #第二个参数:起始位置,第三个参数:截取长度
    my $minx = substr("fred J. Flintstone", 8, 5); #Flint
    
    my $peb = substr "fred J. Flintstone", 13; #stone 不加第三个参数,默认到最后
    
    my $out = substr("some very long string",-3,2); #in 倒数第三个字符开始
    
    #与index结合使用
    my $long = "some very very long string";
    my $right = substr($long, index($long,"l"); #long string
    
    #修改字符串
    my $string = "hello, world";
    substr($string, 0, 5) = "goodbye"; #goodbye, world  可见长度不一定相同
    
    #替换
    substr($string, -20) =~ s/fred/barney/g; #只替换字符串后20个中匹配字符
    

    sprintf格式化字符串

    不同于printf的是它能赋值给变量

    my $date = sprintf "%4d %02d",$yr,$mo; 
    my $money = sprintf "%.2f",2.3456;
    

    排序

    #数组排序
    my @numbers = sort {$a <=> $b} @some_numbers; #数值
    my @string = sort {$a cmp $b} @some_strings; #字符串
    
    my @descending = reverse sort {$a <=> $b} @some_numbers;
    my @descending = sort {$b <=> $a} @some_numbers; #结果同上
    
    #哈希值排序
    sort keys %hash #这是对键排序
    sort{$hash{$b} <=> $hash{$a}} keys %hash #值排序,降序
    sort{$hash{$a} <=> $hash{$b}} keys %hash #升序
    #sort values %hash ???
    
    #先按值再按键排序
    my @winner = sort by_score_name keys %score;
    sub by_score_name{
        $score{$b} <=> $score{$a} #根据分数降序排列
          or
        $a cmp $b  #分数相同再按名字排序
    }
    #飞船操作符返回-1或1,都为真,两数相同时返回0。
    #再加or,可进行多级排序
    

    -------第十五章 智能匹配与given-when结构------------

    智能匹配操作符~~

    会根据两边操作数的数据类型自动判断何种方式进行比较和匹配,一般与前后顺序无关,特殊情况外。

    say "I found fred in the same" if $name ~~ /Fred/;
    

    对不同操作数的处理:

    %a ~~ %b #键是否相等
    %a ~~ @b 或@a ~~ %b #a键是否在数组b中
    %a ~~ /fred/ 或/fred/ ~~ %b  #键匹配
    'fred' ~~ %a  #哈希值$a{fred}是否存在
    @a ~~ @b #数组是否相同
    @a ~~ /fred/ #数组中至少一个元素匹配
    $name ~~ /fred/ #模式匹配
    'fred' ~~ 'fred' #字符串是否相同
    123 ~~ 456 #数组是否相等
    

    示例1:%names中是否匹配fred键,若有打印

    #传统写法:
    my $flag = 0;
    foreach my $key (keys %name){
        next unless $key =~ /fred/;
        $flag = $key;
        last;
    }
    print "the key is $flag\n" if $flag;
    
    #智能匹配:
    say "sucess" if %names ~~ /fred/; #或if /fred/ ~~ %names
    

    示例2:判断两个等长的数组是否完全相同

    #传统写法:
    my $equal = 0;
    foreach my $index (0..$#names1){
        last unless $names1[$index] eq $names[$index];
        $equal++;
    }
    print "yes\n" if $equal == @names1;
    
    #智能匹配:
    say "yes" if @names1 ~~ @names2;
    
    • given语句
      given-when多条件,类似c语言switch语句。
    given ($ARGV[0]){
        when('fred'){say "1"} #实际是$_ =~    或$_ ~~
        when(/Fred/i){say "2"}
        when(/\AFred/){say "3"}
        default {say "4"}
    }
    #和if-elsif-else语句的区别在于:given-when可在满足某条件的基础继续测试其他条件,而if-else-elsif-else则非此即彼。
    #每个条件也可加break/continue等控制
    
    

    多个条目的when匹配

    将given放到foreach中循环测试

    foreach my $name(@names){
        given($name){
            ...
        }
    }
    
    ##可简化以下形式:
    foreach(@names){ #不使用具名控制变量
        say "\nProcessing $_";
        
        when('fred'){say "1"; continue}  #continue使每个条件都能执行
        when(/Fred/i){say "2"; continue}
        when(/\AFred/){say "3"}
        say "moving on to default...";
        default {say "4"}
    }
    
    

    ----------第十六章 进程管理----------------------

    system函数

    perl程序为父进程,system为子进程。

    #一般就是shell命令。
    system 'date';
    
    system 'ls -l $HOME'; 
    #此处用双引号,会将$HOME视为变量内插,而非环境变量
    
    system 'for i in *; do echo ==$i==; cat $i; done &';
    #里面的命令为孙进程;&放后台运行,perl程序无需等待它运行完
    
    #不使用shell命令,则用多参数:
    system 'tar','cvf',$tarfile, @dirs;
    

    环境变量

    %ENV : 每个键都代表一个环境变量  
    $ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
    

    其他类system函数和命令

    #1.exec函数
    exec 'date';
    #不能在后台运行,一般很少用
    
    #2. 反引号
    print "the time is now: ", `date`;
    my $out_errors = `frobnitz -enable 2>&1`; #将标准错误合并至标准输出
    #建议如果不需要捕获输出内容,就不要用反引号。
    
    #3. qx操作符
    qx(perldoc -t -f int) #近似反引号
    
    #建议还是用system函数
    

    ------第十七章 高级Perl技巧-------------------

    切片

    #标量:
    my $count = (split /:/)[5];
    my($card,$count) = (split /:/)[1,5];
    my($first, $last) = (sort @names) [0,-1] #取第一个和最后一个
    
    #数组切片:
    my @num = @names[9,2,1,0,1];
    #下标可任意顺序,也可重复
    
    #哈希切片:
    my @three_scores = @score { qw/barney fred dino/ }
    #等于:my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
    
    my @name = qw /a b c/;
    my @math_score = qw /1 2 3/;
    @score{@name} = @math_score; #相当于构建哈希
    print "their scores were: @score{@name}\n"; #也能内插
    

    捕获错误

    • eval表达式
      检查到致命错误立即停止运行整个eval块,退出后继续运行其余代码。
      默认返回语句块最后一条表达式结果。若捕获到错误,整个语句块返回undef,并在特殊变量$@中设置错误消息。
    #如对除0错误的处理:
    my $barney = eval {$fred/$dino} // 'NaN'; #将NaN设为默认值
    print "I can't divide by \$dino : $@" if $@;
    
    #检查返回值来判断
    unless (eval { $fred/$dino}){
        print "I can't divide by \$dino : $@" if $@;
    }
    
    #对多处潜在(打开文件/除0/子程序等)的致命错误做防范:
    foreach my $person (qw /one wtow three four/){
        eval{
            open my $fh, '<', $person or die "can't open file: $!";
            my ($total, $count);
            while(<$fh>){
                $total += $_;
                $count++;
            }
            my $average = $total/$count; #eval也可在此嵌套
            print "average for file $person was $average\n";
            
            &do_something($person,$average);
        }
        if($@){
            print "an error occurred ($@),continuing\n";
        }
    }
    
    #但有些错误是eval无法捕获的:
    #如语法错误;perl解释器崩溃;警告信息;exit操作符
    

    高级错误处理

    Perl语言处理错误的基本做法:用die抛出异常,用eval捕获异常,通过识别$@中的错误消息判断问题出在哪里。

    #local $@;
    eval{
        ...;
        die "a unexpected message" if $unexpected;
        die "bad denominator" if $dino == 0;
        $barney = $fred/$dino;
    }
    if( $@ =~ /unexpected/){...;}elsif($@ =~ /denominator/){...;}
    #这类代码有很多弊端,如$@的动态作用域问题,确保不干扰高层eval错误。
    #这里最好在最前加上local $@;
    
    
    #Try::Tiny模块解决这类问题:
    use Try::Tiny;
    try{...;} #可能抛出异常的代码
    catch{...;} #处理异常的代码
    finally{...;} #不管是否出错都运行的代码
    
    my $barney = 
        try{$fred/$dino}
        catch{say "error is $_";} #$_替代$@,避免干扰
        finally{say @_? 'error' : 'worked';}; #@_判断参数内容
        
        
    #autodie:
    #perl自带autodie编译指令,自动抛出异常
    use autodie;
    open my $fh, '>', $filename;
    

    grep函数处理列表元素

    返回真假值

    my @odd_numbers = grep { $_ % 2} 1..1000; #挑出奇数
    
    my @match_lines = grep {/\bfred\b/i} <$fh>;
    my @match_lines = grep /\bfred\b/i/, <$fh>; 
    #若只有一个表达式,可去掉大括号加逗号进行简化
    
    my $line_count = grep /\bfred\b/i, <$fh>; #标量,返回匹配个数
    

    map函数处理列表元素

    返回实际结果

    my @data = (4.5,6.23,67);
    my @format_data = map {&big_money} @data; #对金额数字格式化
    print "the money are: \n", map {sprintf("%25s\n", $_)} @format_data;
    
    #简单表达式同样可简化:
    print "some powers of two are:\n",
        map "\t".(2**$_)."\n", 0..15;
    

    其他处理列表元素函数

    Perl自带的List::Util模块

    #first函数:
    my $first_match = first {/\bfred\b/i} @names; 
    
    #sum函数
    my $total = sum(1..100);
    
    #max函数
    my $max = max(3,5,4,7);
    
    #maxstr函数:最长字符串
    my $max = maxstr(@strings);
    
    #shuffle函数:对列表元素随机排序
    my @shuffled = shuffle(1..1000);
    

    List::MoreUtils模块

    #none/any/all函数
    if(none {$_>100} @numbers){...;} 
    elsif(any {$_ >50} @numbers){...;}
    elsif(all {$_ <10} @numbers){...;}
    
    #natatime函数(n at a time,同时处理n组)
    my $iterator = natatime 3, @array;
    
    #mesh函数:合并多个列表(交错填充)
    my @large_array = mesh @one, @two, @three;
    
  • 相关阅读:
    第四章 瞬时响应:网站的高性能架构(待续)
    第三章 大型网站核心架构要素(待续)
    Luogu P1140 相似基因 【dp】By cellur925
    矩阵快速幂/矩阵加速线性数列 By cellur925
    [POI2008]BLO-Blockade 【无向图tarjan/鸽点】By cellur925
    USACO Training3.3 A Game【区间Dp】 By cellur925
    Luogu P2858 [USACO06FEB]奶牛零食Treats for the Cows 【区间dp】By cellur925
    Luogu P2921 在农场万圣节 【tarjan in 有向图】 By cellur925
    浅谈扩展欧几里得[exgcd] By cellur925
    NOIp 2014 联合权值 By cellur925
  • 原文地址:https://www.cnblogs.com/jessepeng/p/10962660.html
Copyright © 2011-2022 走看看