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

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;

Perl语言入门14-17的更多相关文章

  1. Perl语言入门: 斜线不是元字符,所以在不作为分隔符时不需要加上反斜线。

    Perl语言入门: 斜线不是元字符,所以在不作为分隔符时不需要加上反斜线.

  2. Perl语言入门

    Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 "实用报表提取语言". Perl语法基础: (1)Perl程序由声 ...

  3. Perl语言入门:第六章习题:处理用户所指定的名字并汇报相应的姓。

    37 print "\n----------------------------------_exercise_6_1--------------------------\n";  ...

  4. Perl 语言入门6-9

    ---- 第6章 哈希----------- 简介 键值对.键和值都是任意标量,但键总是会被转换成字符串. 键唯一,值可重复. 应用场景:一组数据对应到另一组数据时. 如找出重复/唯一/交叉引用/查表 ...

  5. Perl语言入门(中文版)(第6版) 东南大学出版社

    第一章简介 问题与答案 这本书适合你吗? 为何有这么多的脚注? 关于习题和解答? 习题前标的数字是什么意思? 如果我是Perl讲师? “Perl”这个词表示什么意思? Larry为什么要创造Perl? ...

  6. Perl 语言入门1-5

    第一章 简介 perl -v 文字处理,编写小型CGI脚本(Web服务器调用程序)的最佳语言 CPAN: Perl综合典藏网 shebang: #! /usr/bin/perl 或#! /usr/lo ...

  7. Perl语言入门--3--文件读取与写入

    现有文件test.txt,内容为:"123\n456" 1,打开文本test.txt #!/usr/bin/perl open d,"test.txt"; d ...

  8. Perl语言入门--4--列表

    1.列表也是数组的形式:(1,'a',2,3,4) 元素可以是任意类型,变量,表达式 2.空列表:() 单元素列表:(2)  .与值2不同 qw(1 $a str)   #qw是用空格作为分隔符,元素 ...

  9. Perl语言入门--2--perl的运算符

    一.算数运算符 **:是幂 结果不能超过数的范围 当指数为小数时 底数不能为负数 %:取余数  两边的操作数为整数,如果不是则要截取,把所有的小数部分去掉 注意:当一个字符串参加运算,需要转化为整数时 ...

随机推荐

  1. 【UE4 调试】提升UE4源码版本Setup下载速度

    更改setup.bat部分参数

  2. [no code][scrum meeting] Beta 9

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月23日15:30,主持者:肖思炀 下次例会时间:5月25日11:30,主持者:伦泽标 一.工作 ...

  3. Beta阶段第八次会议

    Beta阶段第八次会议 时间:2020.5.24 完成工作 姓名 工作 难度 完成度 ltx 1.修改一下小程序游客模式的风格 轻 80% xyq 1.针对昨天提出的意见对场地申请表格进行修改 中 9 ...

  4. Scrum Meeting 最终总结

    [软工小白菜]Scrum Meeting 最终总结 2020/4/28 一.会议内容 1.工作及计划 组员代号 完成的工作 明日计划 炎龙 1.整合了整个程序,生成了apk并且上传审核 无 风鹰 1. ...

  5. [no_code团队]项目介绍 & 需求分析 & 发布预测

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 博客园班级博客 作业要求 团队项目选择 我们在这个课程的目标是 在团队合作中提升软件开发水平 这个作业在哪个具体方面帮助我们实现目标 进行项目 ...

  6. flutter页面间跳转和传参-Navigator的使用

    flutter页面间跳转和传参-Navigator的使用 概述 flutter中的默认导航分成两种,一种是命名的路由,一种是构建路由. 命名路由 这种路由需要一开始现在创建App的时候定义 new M ...

  7. zip和flatMap没有生效

    在Reactor 中flatMap和zip等没有生效 1.一个简单的示例代码如下: 2.示例运行结果 3.得到结论 最近在项目中使用了 Project Reactor ,但发现代码在写着写着有些地方没 ...

  8. sort方法和自定义比较器的写法

    摘要 在做一些算法题时常常会需要对数组.自定义对象.集合进行排序. 在java中对数组排序提供了Arrays.sort()方法,对集合排序提供Collections.sort()方法.对自定义对象排序 ...

  9. 实验 1: SDN拓扑实践

    (图片和文档是自己写的,因为在CSDN也写了,所以会有自己的水印) 一.实验目的 能够使用源码安装Mininet: 能够使用Mininet的可视化工具生成拓扑: 能够使用Mininet的命令行生成特定 ...

  10. LCA-离线tarjan模板

    /* *算法引入: *树上两点的最近公共祖先; *对于有根树的两个结点u,v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u,v的祖先且x的深度尽可能大; *对于x来说,从u到v的路径一定 ...